静态方法、类方法和类属性
- 实例方法
- 语法:必须有一个参数,这个参数表示当前实例对象,一般是self
- 调用:只能通过实例对象调用
- 类方法
- 语法:必须有一个参数,这个参数表示当前类对象,一般是cls,在方法的头部加注释(装饰器)@classmethod
- 调用:实例对象可以调用,类对象也可以调用
- 静态方法
- 语法:普通函数的格式,不需要强制的要求传递参数,在方法的头部加上注释@staticmethod;一般用于与实例对象,类对象无关的内容
- 实例方法、类方法、静态方法都可以通过实例或者类调用,只不过实例方法通过类调用时需要传递实例的引用
In [43]: class Test(object):
...: def instancefun(self): # 实例方法
...: print('instancefun')
...: print(self)
...: @classmethod
...: def classfun(cls): # 类方法
...: print('classfun')
...: print(cls)
...: @staticmethod
...: def staticfun(): # 静态方法
...: print('staticfun')
...: def function(): # 普通函数
...: print('func')
...:
In [44]: t = Test() # 实例化一个的对象
In [45]: t.instancefun()
instancefun
<__main__.Test object at 0x7f99fc879510>
In [46]: Test.classfun() # 类调用类方法
classfun
<class '__main__.Test'>
In [47]: t.classfun() # 对象调用类方法
classfun
<class '__main__.Test'>
In [48]: Test.staticfun() # 类调用静态方法
staticfun
In [49]: t.staticfun() # 对象调用静态方法
staticfun
In [50]: Test.instancefun(t) # 类调用实例方法需要传递参数
instancefun
<__main__.Test object at 0x7f99fc879510>
- 实例属性
- 实例属性是对象持有的,不是共享的属性
- 实例属性只有对象能够访问
- 类属性
- 定义在类内部,方法的外部的属性就是类属性
- 在类的外部,通过类对象.属性就是类属性
- 实例属性和类属性的区别
- 类属性归所有的实例对象共享,可以通过类名访问,也可以通过实例来访问
- 实例属性归具体某个实例对象所有,只能通过实例对象访问
# 类属性
In [55]: class Person(object):
...: num = 100
...: def __init__(self):
...: self.name = "zzz"
...: def func(self):
...: self.age = 100
...:
In [56]: p1 = Person()
In [57]: p1.name = "aaa" # 通过实例化对象修改属性,发现属性并没有修改
In [58]: p2 = Person()
In [59]: print(p1.name)
aaa
In [60]: print(p2.name)
zzz
In [61]: Person.num = 200 # 通过类对象修改属性,发现属性修改了
In [62]: print(p1.num)
200
In [63]: print(p2.num)
200
- 如果需要在类外修改属性,必须通过类对象去引用然后进行修改;如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用 该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除该实例属性;
- 类中私有属性
- __private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问
- 在类内部的方法中使用时 self.__private_attrs
-
访问私有属性其格式是:对象.类_字段名;
- eg:Test._Test__name或者a._Test__name
In [85]: class Test:
...: __name = 'aaa'
...: def a(self):
...: print Test.__name
...:
In [86]: a = Test()
In [87]: a.a()
aaa
In [88]: print Test.__name # 不能直接访问私有属性
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-88-56cfd6a10fe4> in <module>()
----> 1 print Test.__name
AttributeError: class Test has no attribute '__name'
In [89]: print a._Test__name # 通过实例对象进行访问/也可以通过类对象进行访问
aaa