https://www.cnblogs.com/Keep-Ambition/p/7296492.html
装饰器方法
类的另外的特性,装饰器方法:静态方法(staticmethod)、类方法(classmethod)、属性方法(property)
一、静态方法
在方法名前加上@staticmethod装饰器,表示此方法为静态方法
class Dog(object): def __init__(self,name): self.name = name @staticmethod #在方法前加上staticmethod 装饰器定义静态方法 def eat(): print("dog is eating"
静态方法特性
特性:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性
1、静态方法,是不可以传入self参数的,但是想传也可以,调用时必须传入实例本身
class Dog(object): def __init__(self,name): self.name = name @staticmethod #定义静态方法 def eat(self,food): #可以定义,但是需传入实例本身 print("{0} is eating {1}".format(self.name,food)) d = Dog("shabi") d.eat(d,"hotdog") #传入实例d本身,否则会报错 #输出 shabi is eating hotdog
2、静态方法可以用类直接调用,直接调用时,不可以直接传入self,否则会报错
class Dog(object): def __init__(self,name): self.name = name @staticmethod def eat(food): print("is eating {0}".format(food)) Dog.eat("hotdog") #输出 is eating hotdog
3、静态方法的使用场景,这种场景挺常见,就像os模块的中某些函数一样,都是使用了静态方法
import os os.system() os.mkdir()
二、类方法
在方法名前加上@classmethod装饰器,表示此方法为类方法
class Dog(object): name = "honggege" #定义静态属性 def __init__(self,name): self.name = name @classmethod #定义类方法 def eat(self,food): print("{0} is eating {1}".format(self.name,food))
类方法特性
特性:只能访问类变量(又叫静态属性),不能访问实例变量
1、访问实例变量
class Dog(object): def __init__(self,name): self.name = name @classmethod #定义类方法 def eat(self,food): print("{0} is eating {1}".format(self.name,food)) d = Dog("shabihong") d.eat("hotdog") #输出 File "D:/PycharmProjects/pyhomework/day7/类方法.py", line 11, in <module> d.eat("hotdog") File "D:/PycharmProjects/pyhomework/day7/类方法.py", line 8, in eat print("{0} is eating {1}".format(self.name,food)) AttributeError: type object 'Dog' has no attribute 'name'
2、访问类变量(又叫静态属性)
class Dog(object): name = "honggege" #定义类变量 def __init__(self,name): self.name = name @classmethod def eat(self,food): print("{0} is eating {1}".format(self.name,food)) d = Dog("shabihong") d.eat("hotdog") #输出 honggege is eating hotdog #调用的是类变量
3、使用场景:一般是需要去访问写死的变量,才会用到类方法装饰器
三、属性方法
在方法名前加上@property装饰器,表示此方法为属性方法
class Dog(object): def __init__(self,name): self.name = name @property #定义属性方法 def eat(self): print("{0} is eating".format(self.name))
属性方法特性
特性:把一个方法变成一个静态属性
1、静态属性的调用
class Dog(object): def __init__(self,name): self.name = name @property #定义属性方法 def eat(self): print("{0} is eating".format(self.name)) d = Dog("shabihong") d.eat #把方法变成静态属性调用 #输出 shabihong is eating
2、给转成的静态属性赋值
用@静态方法名.setter(属性装饰器)去装饰方法,来给转换后的静态属性赋值
上面代码没有把food传上去,那是因为传参方法,没有把接收之前的food的赋值,修改成如下代码就能成功上传:
3、删除转变的静态属性
用@静态方法名.deleter(属性装饰器)去装饰,表明可以删除转化后的静态属性
4、静态属性使用场景
一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态必须经历以下几步:
1. 连接航空公司API查询
2. 对查询结果进行解析
3. 返回结果给你的用户
因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以
class Flight(object): def __init__(self,name): self.flight_name = name def checking_status(self): print("checking flight %s status " % self.flight_name) return 1 @property def flight_status(self): status = self.checking_status() if status == 0 : print("flight got canceled...") elif status == 1 : print("flight is arrived...") elif status == 2: print("flight has departured already...") else: print("cannot confirm the flight status...,please check later") @flight_status.setter #修改 def flight_status(self,status): status_dic = { 0 : "canceled", 1 :"arrived", 2 : "departured" } print(" 33[31;1mHas changed the flight status to 33[0m",status_dic.get(status) ) @flight_status.deleter #删除 def flight_status(self): print("status got removed...") f = Flight("CA980") f.flight_status f.flight_status = 2 #触发@flight_status.setter del f.flight_status #触发@flight_status.deleter
装饰器方法总结:
- 静态方法是访问不了类或实例中的任何属性,它已经脱离了类,一般会用在一些工具包中
- 类方法,只能访问类变量,不能访问实例变量
- 属性方法是把一个方法变成一个静态属性
类的特殊成员方法
类的方法,有普通方法,就是我们自己定义的方法,还有装饰器方法(静态方法,类方法,属性方法),其实类还有另外一种方法,叫做类的特殊成员方法
1、 __doc__
说明:表示类的描述信息
1
2
3
4
5
6
7
8
9
10
11
|
class Dog( object ): """此类是形容Dog这个类""" #类的描述信息 def __init__( self ,name): self .name = name print (Dog.__doc__) #打印类的描述信息 #输出 此类是形容Dog这个类 |
2、 __module__和__class__
说明:
- __module__: 表示当前操作的对象在哪个模块
- __class__:表示当前操作的对象的类是什么
aa.py的代码:
1
2
3
4
|
class C( object ): def __init__( self ): self .name = "shuaigaogao" |
index.py的代码:
1
2
3
4
5
6
7
8
9
10
|
from lib.aa import C obj = C() print (obj.__module__) #表示当前操作的对象在哪个模块 print (obj.__class__) #表示当前操作的对象的类是什么 #输出 lib.aa < class 'lib.aa.C' > |
3 、__init__
说明:构造方法,通过类创建对象时,自动触发执行
4、 __del__
说明:析构方法,当对象在内存中被释放时,自动触发执行
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,
所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的
5、 __call__
说明: 对象后面加括号,触发执行
1
2
3
4
5
6
7
8
9
10
11
12
|
class Foo( object ): def __init__( self ): self .name = "shuaigaogao" def __call__( self , * args, * * kwargs): #重写call方法 print ( "running call" ,args,kwargs) f = Foo() #执行__init__ f( 1 , 2 , 3 ,name = 333 ) # 执行call方法,也可以写成 Foo()(1,2,3,name=333) #输出 running call ( 1 , 2 , 3 ) { 'name' : 333 } |
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
6 、__dict__
说明: 查看类或对象中的所有成员
①类.__dict__
效果:打印类中所有的属性,不包括实例属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
class Province( object ): country = 'China' def __init__( self , name, count): self .name = name self .count = count def func( self , * args, * * kwargs): print ( "func" ) print (Province.__dict__) #类.__dict__ #输出 { '__doc__' : None , '__weakref__' : <attribute '__weakref__' of 'Province' objects>, '__init__' : <function Province.__init__ at 0x00000247F3CAD488 >, 'country' : 'China' , '__dict__' : <attribute '__dict__' of 'Province' objects>, 'func' : <function Province.func at 0x00000247F3CAD510 >, '__module__' : '__main__' } #打印类中所有的属性,不包括实例属性 |
②实例名.__dict__
效果:打印该实例的所有属性,不包括类属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class Province( object ): country = 'China' def __init__( self , name, count): self .name = name self .count = count def func( self , * args, * * kwargs): print ( "func" ) p = Province( "jiangsu" , 20000 ) #实例化 print (p.__dict__) #实例名.__dict__ #输出 { 'count' : 20000 , 'name' : 'jiangsu' } #打印该实例的所有属性,不包括类属性 |
7 、__str__
说明:如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class Province( object ): country = 'China' def __init__( self , name): self .name = name def __str__( self ): return "<obj:{0}>" . format ( self .name) p = Province( "jiangsu" ) print (p) #打印这个对象 #输出 <obj:jiangsu> #给对象重新起了一个名字 |
注:这个以后会在django框架里面会用到,这边就不多说了
8 、__getitem__、__setitem__、__delitem__
说明:用于索引操作,如字典。以上分别表示获取、设置、删除数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
class Foo( object ): def __getitem__( self , key): print ( '__getitem__:' ,key) def __setitem__( self , key, value): print ( '__setitem__:' ,key,value) def __delitem__( self , key): print ( '__delitem__' ,key) f = Foo() f[ "name" ] = "shuaigaogao" #自动触发__setitem__方法 f[ "name" ] #自动触发__getitem__方法 del f[ "name" ] #自动触发__delitem__方法 #输出 __setitem__: name shuaigaogao __getitem__: name __delitem__ name |
注:这边的__delitem__没有做真正的删除,只是触发这个方法,想要真正删除,只需要在__delitem__函数中添加删除功能即可