from types import MethodType
class Student(object):
pass
def set_name(self, name):
self.name = name
s1 = Student()
s2 = Student()
s3 = Student()
# 为实例单独添加方法,Student类没有set_name方法,若Student的其他实例未添set_name方法,则他实例无法调用set_name,
# 每次调用仅作用于实例自身的name属性
s1.set_name = MethodType(set_name, s1)
s2.set_name = MethodType(set_name, s2)
s1.set_name('tom')
s2.set_name('tony')
print(hasattr(Student, 'set_name'))
# False
print(hasattr(s3, 'set_name'))
# False
print(s1.name, s2.name)
# tom tony
# 为Student设置set_name方法,每个实例都可以调用set_name方法,
# 每次调用作用于Student类的name
Student.set_name = MethodType(set_name, Student)
s1 = Student()
s2 = Student()
s1.set_name('tom')
s2.set_name('tony')
# 由于实例没有name属性,因此会直接返回Student类的name属性
print(s1.name, s2.name)
# tony tony
# 如果为每个实例单独设置name属性,则会返回每个实例自己的name属性
s1.name = 'tom'
s2.name = 'tony'
print(s1.name, s2.name)
# tom tony
# 从上面的例子可以看出,在编写程序的时候,
# 千万不要对实例属性和类属性使用相同的名字,
# 因为相同名称的实例属性将屏蔽掉类属性,
# 但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。
# 为Student添加方法,每个实例都可以调用set_name方法,
# 每次调用仅作用于实例自身的name属性
Student.set_name = set_name
s1 = Student()
s2 = Student()
s1.set_name('tom')
s2.set_name('tony')
print(hasattr(Student, 'set_name'))
print(s1.name, s2.name)
# tom tony