Discuss / Python / __slots__ 的 个人小发现

__slots__ 的 个人小发现

Topic source

先看代码:

class Student(object):
	__slots__ = ('name','score','set_age')

stu = Student()
stu.name = 'Zhangsan'
stu.score = 90
#stu.age = 20  无法添加该属性

print(stu.name) #正常打印
print(stu.score) #正常打印
#print(stu.age) 无法打印

Student.age = 20

print(stu.age) #正常打印

通过上面我们发现使用__slots__限制的仅仅是类的实例的属性或者方法的动态添加,类本身的属性的添加不受__slots__的限制。

说明二:

from types import MethodType
class Student(object):
	__slots__ = ('name','score','set_age')

stu = Student()
stu.name = 'Zhangsan'
stu.score = 90

def set_age(self,age):
	self.age = age

stu.set_age = MethodType(set_age,stu)
stu.set_age(20)

当执行这个py 文件后,报错:AttributeError: 'Student' object has no attribute 'age'  这个可以告诉我们在给类的实例添加方法时,不能添加__slots__限制之外的属性。此处即添加了age参数。不在__slots__ 限制属性内。

不错

mf734

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

小白。如果说错请纠正赐教。

看了你的,我又试了试MethodType(set_age, Student),同样也是添加不进去,报错是type object has no attribute。总结起来,就是不管是类还是实例的__slot__,都不能用MethodType,但是都可以用A.B(A是对象,B是attribute)来赋值。所以我在想是不是__slot__本身就是专门限制绑定方法的。

Vuean

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

我试了

stu.set_age = MethodType(set_age, Student)
stu.set_age(20)
print(stu.age)keyi

可以执行呀???难道添加的不对?

不是很懂

JX锦侠

#5 Created at ... [Delete] [Delete and Lock User]
from types import MethodType

class Student(object):
    __slots__ = ('set_gender')

def set_gender(self, gender):
    self.gender = gender

stu = Student()

# 给实例添加方法
stu.set_gender = MethodType(set_gender, stu)
# 调用实例的方法失败
stu.set_gender('male')  # AttributeError

# 给类添加方法
Student.set_gender = set_gender
# 调用实例的方法失败
stu.set_gender('male')  # AttributeError

# 给类添加方法
Student.set_gender = MethodType(set_gender, Student)
# 调用实例的方法成功
stu.set_gender('male')  # 没有报错

最后给类添加方法的这两种方式有什么区别吗?求大神解答……


人玉匆花

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

stu.set_age = MethodType(set_age,Student)

添加的是类属性的age,__slots__限制的是实例属性的添加,不限制类属性添加。

print(stu.age) 返回的是类属性的age,只读属性。

codedig

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

@Vuean
你能成功的原因是, 你的

stu.set_age = MethodType(set_age, Student)

第二个参数是类,而不是实例;给类绑定是不受: __slots__ 限制的

codedig

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

@JX锦侠

我上一个回答,回答了你最后一个为啥成功的原因;
你第二个失败的原因是, Student.set_gender = set_gender 这个行为并没有绑定函数给 Stedent 类,
因为给Stedent 绑定函数的方式,不是直接赋予函数名;而是要使用MethodType() 函数才对

codedig

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

楼主的总结,小弟受教了. 厉害


  • 1

Reply