python 面向对象静态方法、类方法、属性方法、类的特殊成员方法
静态方法:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性。
在类中方法定义前添加@staticmethod,该方法就与类中的其他(属性,方法)没有关系,不能通过实例化类调用方法使用类变量,只能单纯的使用方法本身。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class dog( object ): def __init__( self ,name): self .name = name def eat( self ,food): print '%s吃%s' % ( self .name,food) a = [ 'q' , 'a' , 'z' ] for i in a: d = dog(i) d.eat( 'baozi' ) 结果: q吃baozi a吃baozi z吃baozi |
1 2 3 4 5 6 7 8 9 10 | class dog( object ): def __init__( self ,name): self .name = name @staticmethod #实际跟类没有任何关系。 def eat( self ,food): print '%s吃%s' % ( self .name,food) a = [ 'q' , 'a' , 'z' ] for i in a: d = dog(i) d.eat( 'baozi' ) |
结果:
Traceback (most recent call last):
File "C:\Users\xuxia\workspace\helloword\src\test\lianx_2.py", line 223, in <module>
d.eat('baozi')
TypeError: eat() takes exactly 2 arguments (1 given)
1 2 3 4 5 6 7 8 9 10 | class dog( object ): def __init__( self ,name): self .name = name @staticmethod def eat(): print '%s吃%s' % ( 'w' , 'e' ) d = dog( 'tt' ) d.eat() 结果:w吃e |
类方法:只能访问类变量,不能访问实例变量。
1 2 3 4 5 6 7 8 9 10 | class dog( object ): name = 'hh' def __init__( self ,name): self .name = name @classmethod def eat( self ): print '%s吃%s' % ( self .name, 'e' ) d = dog( 'tt' ) d.eat() 结果:hh吃e |
属性方法:把一个方法变成静态属性。
1 2 3 4 5 6 7 8 9 10 | class dog( object ): name = 'hh' def __init__( self ,name): self .name = name @property def eat( self ): print '%s吃%s' % ( self .name, 'e' ) d = dog( 'tt' ) d.eat # 结果:tt吃e |
如果给属性方法传参数,需要重新写方法,如:eat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class dog( object ): name = 'hh' def __init__( self ,name): self .name = name @property def eat( self ): print '%s吃%s' % ( self .name, 'e' ) @eat .setter def eat( self ,food): print '%s is eating %s' % ( self .name,food) d = dog( 'tt' ) d.eat = 'baozi' 结果:tt is eating baozi |
类的特殊成员方法:
ddd.py
1 2 3 4 5 | class c( object ): def __init__( self ,name): self .name = name def a( self ): print 'bb%s' % self .name |
1 2 3 | from ddd import c b = c( 'ee' ) print b.__module__ |
结果:ddd
1 | print b.__class__ |
结果:<class 'ddd.c'>
__call__ 对象后面加括号,触发执行。
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class dog( object ): '''方法__call__实例''' def __init__( self ,name): self .name = name def a( self ): print 'sssss%s' % self .name def __call__( self , * c, * * f): print c,f d = dog( 'ddd' ) d.a() dog( 'ddd' )( 1 , 2 , 3 ,f = 'fff' ) 结果: sssssddd ( 1 , 2 , 3 ) { 'f' : 'fff' } |
__dict__ 查看类或对象中的所有成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class dog( object ): '''方法__dict__实例''' def __init__( self ,name,food): self .name = name self .food = food def a( self ): print 'sssss%s' % self .name def __call__( self , * c, * * f): print c,f print dog.__dict__ d = dog( 'ddd' , 'nome' ) print d.__dict__ #打印所有类属性,不包括类变量 结果: { 'a' : <function a at 0x02229C70 >, '__module__' : '__main__' , '__dict__' : <attribute '__dict__' of 'dog' objects>, '__call__' : <function __call__ at 0x02229C30 >, '__weakref__' : <attribute '__weakref__' of 'dog' objects>, '__doc__' : '\xe6\x96\xb9\xe6\xb3\x95__call__\xe5\xae\x9e\xe4\xbe\x8b' , '__init__' : <function __init__ at 0x02229CB0 >} { 'food' : 'nome' , 'name' : 'ddd' } |
__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class dog( object ): '''方法__str__实例''' def __init__( self ,name,food): self .name = name self .food = food def a( self ): print 'sssss%s' % self .name return self .name #实例化后方法的返回值,实例化后必须复制给变量 def __call__( self , * c, * * f): print c,f def __str__( self ): return self .food #类的返回值,实例化后指对象的返回值 d = dog( 'xx' , 'yy' ) f = d.a() print f print d 结果: sssssxx xx yy |
__getitem__、__setitem__、__delitem__
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Foo( object ): '''__getitem__、__setitem__、__delitem__实例''' def __getitem__( self , key): print ( '__getitem__' ,key) def __setitem__( self , key, value): print ( '__setitem__' ,key,value) def __delitem__( self , key): print ( '__delitem__' ,key) obj = Foo() result = obj[ 'k1' ] # 自动触发执行 __getitem__ obj[ 'k2' ] = 'alex' # 自动触发执行 __setitem__ del obj[ 'k1' ] 结果: ( '__getitem__' , 'k1' ) ( '__setitem__' , 'k2' , 'alex' ) ( '__delitem__' , 'k1' ) |
__new__ \ __metaclass__
1 2 3 4 | class Foo( object ): def __init__( self ,name): self .name = name f = Foo( "alex" ) |
上述代码中,f 是通过 Foo 类实例化的对象,其实,不仅 f是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象。
如果按照一切事物都是对象的理论:f对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。
1 2 | print type (f) # 输出:<class '__main__.Foo'> 表示,obj 对象由Foo类创建 print type (Foo) # 输出:<type 'type'> 表示,Foo类对象由 type 类创建 |
所以,f对象是Foo类的一个实例,Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。
那么,创建类就可以有两种方式:
a). 普通方式
1 2 3 4 | class Foo( object ): def func( self ): print 'hello alex' |
b). 特殊方式
1 2 3 4 5 6 7 | def func( self ): print 'hello wupeiqi' Foo = type ( 'Foo' ,( object ,), { 'func' : func}) #type第一个参数:类名 #type第二个参数:当前类的基类 #type第三个参数:类的成员 |
1 2 3 4 5 6 7 8 9 | def f( self ): print "f" def __init__( self ,name): self .name = name foo = type ( 'foo' ,( object ,),{ '__init__' :__init__, 'f' :f}) #注意元祖object后有逗号 d = foo( 'xx' ) d.f() 结果:f |
__new__:用来创建实例的。
类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__,一般不要写__new__方法,因为该方法已经在类中写好,重写的话,只能覆盖类中的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class foo( object ): def __init__( self ,name): self .name = name print '__init__%s' % self .name def __new__( cls , * c, * * f): #先创建new方法 print '__new__' return object .__new__( cls ) #通过__new__方法创建(触发)__init__方法 f = foo( 'xx' ) print f 结果: __new__ __init__xx <__main__.foo object at 0x021E51F0 > |
类中有一个属性 __metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程
详细查看:http://www.cnblogs.com/alex3714/articles/5213184.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步