Discuss / Python / 使用__slots__和setattr的错误

使用__slots__和setattr的错误

Topic source

久疤_796

#1 Created at ... [Delete] [Delete and Lock User]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

'使用__slots__'

__author__ = 'HZF'

class Stu(object):
    def __init__(self,name):
        self.__name = name

s1 = Stu('Miao')
s1.num = '12300'
print(s1.num)

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

from types import MethodType
s1.setAge = MethodType(setAge,s1)
print(dir(s1))
s1.setAge(15)
print(dir(s1))
setattr(s1,'code',12)
print(dir(s1))
print(s1.age,s1.num,s1.code)

s2 = Stu('Ming')
print(dir(s2))
#对s1对象绑定的数据、方法,在s2中并没有
#如何给该类的所有对象绑定数据、方法
#直接给该类绑定即可
Stu.setAge = MethodType(setAge,Stu)
print(dir(s2))
print(dir(Stu))

#但是,不管怎样的数据、方法都可以绑定,这样真的好吗?
#解决:__slots__

class Stu2(object):
    __slots__ = ('time','name','age','setName','getName','setAge','getAge')

s3 = Stu2()
#打印dir(s3)发现__slots__限制的内容,竟然已经存在了,但是还不能直接调用
#需要绑定后才可以,比如:getAge
#但是还不能直接用,因为没有age
print('s3',dir(s3))
#print(s3.name)
s3.name = 'Duo'
s3.age = 25
#s3.score = 95
print(dir(Stu2))

def setAge(self,age):
    self.age = age
def getAge(self):
    return self.age
def setName(self,name):
    self.name = name
def getName(self):
    return self.name
Stu2.setAge = MethodType(setAge,Stu2)
setattr(Stu2,'getAge',getAge)
setattr(Stu2,'getName',getName)
setattr(Stu2,'setName',setName)
setattr(Stu2,'age',-1)
setattr(Stu2,'name','HZF')
#Stu2.name = 'HZF'
print(Stu2().getAge())
print(Stu2().getName())

#绑定数据、方法到对象、类
#可用setattr,也可以用MethodType

#使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,
#对继承的子类是不起作用的:
#除非在子类中也定义__slots__,这样,
#子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。
class Stu3(Stu2):
    pass
print(dir(Stu3))
s4 = Stu3()
s4.name = 123
s4.kkkk = 'hello'

class Stu4(Stu2):
    __slots__ = ('name','age')
    pass
s5 = Stu4()
print(dir(s5))
#s5.kkk = 123
s5.setName('Juny')
s5.setAge(25)
s5.age = 26
s5.time = 30

#发现上面setattr(Stu2,'name','HZF')导致Stu4的__slots__必须加入'name',
#否则read-only?age同理
#可能是setattr属性导致的?
#可能是由于修改了类Stu2的可附加属性的默认值?

  • 1

Reply