Python面向对象学习(2)

[0]Python类可以在定义的时候就添加方法,这是属于类的方法.还可以给一个实例添加方法,这是属于该实例的方法:

from types import MethodType
class Student(object):
    def display(self):
         print('age:%d'%self.age)

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

#给实例添加
s = Student()
s.set_age = MethodType(set_age,s)
s.set_age(22)
s.display()

这样就为实例s添加了一个方法,这个方法只有s可以用.

[1]给类添加方法:

给类添加方法,这样所有的实例都可以用这个方法了.同时所有的子类和子类的实例也可以用这个方法

##给雷添加方法
Student.set_age = MethodType(set_age,Student)
s2 = Student()
s2.set_age(23)
s2.display()
 class GraduateStudent(Student): pass ##测试子类 gs = GraduateStudent() gs.set_age(25) gs.display() 

[2]注意,调用类的方法添加的任何属性都是属于整个类的.其它实例也可以使用


#给类添加
Student.set_age = MethodType(set_age,Student)
s2 = Student()
s2.set_age(23)
s2.display()

#
s.display()//23
s.age = 5
s.display()//5

这说明s2添加的属性age是属于整个类所有的,s在没有自己属性的情况下可以使用它.一旦s添加了自己的age,那么它就会用自己的age.所以不要随意使用属于类的方法,因为这会影响很多实例.同时设计类的属性时不要将一些不属于公共属性的属性设置为雷属性,比如age,这样从逻辑上和使用上都是合适的.

======================================================================================

slot的使用:

[0]:在类的属性中设置slot,可以在一定程度上限制对该类实例属性和方法的添加,只能添加slot里面的内容,不管是属性还是方法都只能添加slot里面的内容.比如:

from types import MethodType
class Student(object):
    __slots__ = ('name','score')
    def display(self):
         print('age:%d'%self.age)

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

s.age = 5
print(s.age)## object Student has no attributes 'age'

[1]:但是,一定程度上可以绕过这个限制.我们可以对类进行属性的添加,就是slot对类属性不起作用。

def set_city(self, city):
    self.city=city


class Student1(object):
    __slots__ = ('name', 'age')
    pass

s = Student1() 
Student1.age = 5

Student1.set_city = MethodType(set_city,Student1)
s.set_city('beijing')
print(s.city)

注意到,可以给类随意的添加方法和属性.这样实例也可以引用了.当然了,实例还是不能拥有自己的不属于slot的属性.

[2]:slot对于子类的限制:假如子类没有定义自己的slot,那么它的实例是不会受到影响的.

s1 = GraduateStudent()
s1.test = 9
print(s1.test)

s1这个子类实例还是可以随便添加.

但是如果子类添加了slot,那么就不可以随便添加属性和方法了

class GraduateStudent(Student):
    __slots__ = ('fuc')
    pass
def set_age(self,age):
    self.age = age

s = Student()
s.set_age = MethodType(set_age,s)
s.set_age(22)
s.display()
s1 = GraduateStudent()
s1.test = 9##会出错
print(s1.test)

如果子类添加了slot,那么子类实例的限制就是父类和子类的slot.

class GraduateStudent(Student):
    __slots__ = ('fuc')
    pass
def set_age(self,age):
    self.age = age

s = Student()
s.set_age = MethodType(set_age,s)
s.set_age(22)
s.display()
s1 = GraduateStudent()
s1.test = 9
print(s1.test)

最后注意:无论如何,类的属性和方法不会被slot限制

你可能感兴趣的:(Python面向对象学习(2))