属性方法
- 属性方法的作用就是通过@property把一个方法变成一个静态属性
- 属性方法:把一个方法变成静态属性,属性不能通过加()调用
class Dog(object): def __init__(self, name): self.name = name @property def eat(self): print(" %s is eating" % self.name) d = Dog("zouzou") d.eat() # d.eat
调用会出以下错误, 说NoneType is not callable, 因为eat此时已经变成一个静态属性了, 不是方法了, 想调用已经不需要加()号了,直接d.eat就可以了
class Dog(object): name = '金三胖' def __init__(self, name): self.name = name @property # 属性方法 def eat(self): print('%s is eating %s' % (self.name, '鸡蛋')) def talk(self): print('%s is talking' % self.name) d = Dog('叶良辰') d.eat # 属性方法里不需要括号调用 d.talk()
结果:
叶良辰 is eating 鸡蛋 叶良辰 is talking
这种只适合 eat 方法没有参数的
class Dog(object): name = '金三胖' def __init__(self, name): self.name = name self.___food = None # 声明一个私有属性food @property # 把一个方法变成属性 def eat(self): print('%s is eating %s' % (self.name, self.___food)) @eat.setter # 为了给上面的eat属性赋值 def eat(self, food): print('set to food:', self.___food) self.___food = food @eat.deleter # 用于删除属性 def eat(self): del self.___food print('删掉了') def talk(self): print('%s is talking' % self.name) d = Dog('叶良辰') d.eat # 属性方法里不需要括号调用 d.eat = '鸡蛋' d.eat del d.eat # d.eat 已经删掉了,调用会报错
结果:
叶良辰 is eating None set to food: None 叶良辰 is eating 鸡蛋 删掉了
执行d.eat='鸡蛋',其实执行的是@eat.setter下面的方法,把鸡蛋传给了food,执行了self.___food=food(给私有变量重新赋值)。执行del d.eat,其实执行的是 @eat.deleter下的方法,执行了del self.___food(删除了私有变量)
类方法
类方法:类方法只能访问类变量,不能访问实例变量
类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量
类方法的应用场景:
- 类中 有些方法是不需要对象参与.
- 对类中的静态变量进行改变,要用类方法.
- 继承中,父类得到子类的类空间.
类方法: 通过类名调用的方法,类方法中第一个参数约定俗称cls,python自动将类名(类空间)传给cls.
class A: def func(self): print(self) @classmethod # 类方法 def func1(cls): print(cls) a1 = A() a1.func() # 把类A的内存地址传给了self a1.func1() # 把类A的类空间传给了cls,对象调用类方法,cls 得到的是类本身. A.func1() # 把类A的类空间传给了cls
结果:
<__main__.A object at 0x0307B270> <class '__main__.A'> <class '__main__.A'>
例
class A: name = 'zou' count = 1 @classmethod # 类方法 def func(cls): return cls.name + str(cls.count) # 此方法无需对象参与 # return A.name+str(A.count) print(A.func())
结果:
zou1
继承中,父类得到子类的类空间.
class A: age = 12 @classmethod def func1(cls): # 此方法无需对象参与 print(cls) # 可以对B类的所有的内容可以进行修改. print(cls.age) class B(A): age = 22 B.func1()
结果:
<class '__main__.B'> 22
例
class Dog(object): name = '金三胖' def __init__(self, name): self.name = name @classmethod def eat(self): print('%s is eating %s' % (self.name, '鸡蛋')) # 类变量如果没有name会报错 def talk(self): print('%s is talking' % self.name) d = Dog('叶良辰') d.eat() # 类方法里不需要传参 d.talk()
结果:
金三胖 is eating 鸡蛋 叶良辰 is talking
类方法的变量取的是类变量,如果没有这个类变量则报错
静态方法
静态方法:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性
通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法
class Dog(object): def __init__(self, name): self.name = name @staticmethod # 把eat方法变为静态方法 def eat(self): print("%s is eating" % self.name) d = Dog("ChenRonghua") d.eat()
上面的调用会出以下错误,说是eat需要一个self参数,但调用时却没有传递,没错,当eat变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了
想让上面的代码可以正常工作有两种办法
- 调用时主动传递实例本身给eat方法,即d.eat(d)
- 在eat方法中去掉self参数,但这也意味着,在eat中不能通过self.调用实例中的其它变量了
class Dog(object): def __init__(self, name): self.name = name @staticmethod # 静态方法,只能将实例化的对象传给 def eat(self): # print里用到了self,所以必须传个self print('%s is eating %s' % (self.name, '鸡蛋')) def talk(self): print('%s is talking' % self.name) d = Dog('叶良辰') d.eat(d) # 只能将实例变量传给静态方法 d.talk()
结果:
叶良辰 is eating 鸡蛋 叶良辰 is talking