Discuss / Python / Mark

svcasvawe

#1 Created at ... [Delete] [Delete and Lock User]

四点需要注意: 1、类和实例都可以动态绑定属性和方法。类绑定的属性和方法可以作用于 实例,反之则不可以; 2、类动态绑定方法和实例绑定不同,绑定属性时两者相同 类绑定属性:Student.sex = 'M' 实例绑定属性:s.sex = 'M' 类绑定方法:from types import MethodType def set_sex(self, sex): self.sex = sex Student.set_sex = set_sex 实例绑定方法:from types import MethodType def set_sex(self, sex): self.sex = sex s.set_sex = MethodType(set_sex, s) 3、slots可以限制类和实例的属性。使用slots限制后,类和对应的实例不能随意动态绑定属性 4、slots不可继承。也就是说父类的限制不会继承给子类

深入骨头V

#2 Created at ... [Delete] [Delete and Lock User]

我试了一下,你的第四点理解不对。slots是可以继承的。并且slots还有更多的意思。 当基类加了slots它就对你的属性扩展加了限制,扩展的属性必须在slots这个tuple里。 slots不可继承的理解应该是,你动态增加对象属性,在继承此类时,无法继承刚才增加的属性。 根据我自己的实验

  1. 如果基类使用了slots,子类没有使用slots的情况下子类的属性可以在运行时任意扩展。子类的属性自动继承基类属性
  2. 如果基类使用了slots,子类也使用了slots,子类在运行时的可扩展属性是基类的slots + 子类的slots。不在基类slots中的属性子类不能继承。另一个比较有意思的地方是,如果基类包含一个实例属性,而它没有在基类的slots中,那么子类无法继承此属性,也无法扩展此属性。
class Person(object):
    __slots__ = ('name', 'gender')
    def __init__(self, name, age):
        self.name = name
        self.age = age            

class NewPerson(Person):
    __slots__ = ('height', 'weight')

你可以通过删除子类的slots让子类任意扩展,或者在子类的slots中增加 age 属性,来让子类扩展或者继承 age 属性。而如果你不这么做,那么NewPerson类将永远无法拥有 age 属性。

丨慕慕

#3 Created at ... [Delete] [Delete and Lock User]

class Person(object): slots = ('name', 'gender') def init(self, name, age): self.name = name self.age = age ( 如果基类包含一个实例属性,而它没有在基类的slots中)这个不好理解 而且我用的py3.5去实例化这段代码如我所想,会报错。

class Person(object): ... slots = ('name', 'gender') ... def init(self, name, age): ... self.name = name ... self.age = age ... p1 = Person('julia',25) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 5, in init AttributeError: 'Person' object has no attribute 'age'

你的猜想是对的,前楼的说错了。

slot限制了实例不能用age属性,因此在init实例化中无法对age赋值。

前楼说的应该是类属性, 子类可以继承,但只能读、不能再次赋值。


  • 1

Reply