装饰器方法

类的另外的特性,装饰器方法:静态方法(staticmethod)、类方法(classmethod)、属性方法(property)

1、静态方法

在方法名前加上@staticmethod装饰器,表示此方法为静态方法

class Dog(object):def __init__(self, name):self.name = name@staticmethod  # 在方法前加上staticmethod 装饰器定义静态方法def eat():print("dog is eating")

静态方法特性

特性:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性

静态方法,是不可以传入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

静态方法可以用类直接调用,直接调用时,不可以直接传入self,否则会报错

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Dog(object):def __init__(self,name):self.name = name@staticmethoddef eat(food):print("is eating {0}".format(food))Dog.eat("hotdog")#输出
is eating hotdog

静态方法的使用场景,这种场景挺常见,就像os模块的中某些函数一样,都是使用了静态方法

import osos.system()
os.mkdir()

2、类方法

在方法名前加上@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))

类方法特性

特性:只能访问类变量(又叫静态属性),不能访问实例变量

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
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")# 输出
Traceback (most recent call last):d.eat("hotdog")print("{0} is eating {1}".format(self.name, food))
AttributeError: type object 'Dog' has no attribute 'name'

访问类变量(又叫静态属性)

class Dog(object):name = "honggege"  #定义类变量def __init__(self,name):self.name = name@classmethoddef 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))

属性方法特性

特性:把一个方法变成一个静态属性

静态属性的调用

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
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

给转成的静态属性赋值

用@静态方法名.setter(属性装饰器)去装饰方法,来给转换后的静态属性赋值

class Dog(object):def __init__(self,name):self.name = name@property   #定义属性方法def eat(self):print("{0} is eating {1}".format(self.name,"honggege"))@eat.setter  #定义一个可以传参的方法def eat(self,food):print("set to food:",food)# self.__food = foodd = Dog("shabihong")
d.eat = "hotdog"  #给转成的静态变量赋值
d.eat#输出
set to food: hotdog
shabihong is eating honggege

上面代码没有把food传上去,那是因为传参方法,没有把接收之前的food的赋值,修改成如下代码就能成功上传:

class Dog(object):def __init__(self,name):self.name = nameself.__food = None@property   #定义属性方法def eat(self):print("{0} is eating {1}".format(self.name,self.__food))@eat.setter  #定义可以设置变量赋值def eat(self,food):print("set to food:",food)self.__food = foodd = Dog("shabihong")
d.eat      #第一份赋值的是None
d.eat = "hotdog"
d.eat    #第二个赋值是hotdog#输出
shabihong is eating None
set to food: hotdog
shabihong is eating hotdog   #说明赋值成功

删除转变的静态属性

用@静态方法名.deleter(属性装饰器)去装饰,表明可以删除转化后的静态属性

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Dog(object):def __init__(self,name):self.name = nameself.__food = None@propertydef eat(self):print("{0} is eating {1}".format(self.name,self.__food))@eat.setterdef eat(self,food):print("set to food:",food)self.__food = food@eat.deleter   #定义可以删除eat这个静态属性def eat(self):del self.__foodprint("food 变量删除完毕")d = Dog("shabihong")
del d.eat  #删除静态属性eat#输出
food 变量删除完毕

静态属性使用场景

一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态必须经历以下几步:

  1. 连接航空公司API查询
  2. 对查询结果进行解析
  3. 返回结果给你的用户

因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以

class Flight(object):def __init__(self,name):self.flight_name = namedef checking_status(self):print("checking flight %s status " % self.flight_name)return  1@propertydef 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("\033[31;1mHas changed the flight status to \033[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. 静态方法是访问不了类或实例中的任何属性,它已经脱离了类,一般会用在一些工具包中
  2. 类方法,只能访问类变量,不能访问实例变量
  3. 属性方法是把一个方法变成一个静态属性

类的特殊成员方法

类的方法,有普通方法,就是我们自己定义的方法,还有装饰器方法(静态方法,类方法,属性方法),其实类还有另外一种方法,叫做类的特殊成员方法

1、 __doc__

说明:表示类的描述信息

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Dog(object):"""此类是形容Dog这个类"""    #类的描述信息def __init__(self,name):self.name = nameprint(Dog.__doc__)   #打印类的描述信息#输出
此类是形容Dog这个类

2、 __module____class__

说明:

  • __module__: 表示当前操作的对象在哪个模块
  • __class__:表示当前操作的对象的类是什么
class C(object):def __init__(self):self.name = "shuaigaogao"
from aa import Cobj = C()print(obj.__module__)  # 表示当前操作的对象在哪个模块
print(obj.__class__)  # 表示当前操作的对象的类是什么# 输出
aa
<class 'aa.C'>

3 、__init__

说明:构造方法,通过类创建对象时,自动触发执行

4、 __del__

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的

说明:析构方法,当对象在内存中被释放时,自动触发执行

5、 __call__

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

说明: 对象后面加括号,触发执行

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
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}

6 、__dict__

说明: 查看类或对象中的所有成员

①类.__dict__

效果:打印类中所有的属性,不包括实例属性

class Province(object):country = 'China'def __init__(self, name, count):self.name = nameself.count = countdef func(self, *args, **kwargs):print("func")print(Province.__dict__) #类.__dict__#输出
{'__module__': '__main__', 'country': 'China', '__init__': <function Province.__init__ at 0x033D5C00>, 'func': <function Province.func at 0x033D5AE0>, '__dict__': <attribute '__dict__' of 'Province' objects>, '__weakref__': <attribute '__weakref__' of 'Province' objects>, '__doc__': None}
#打印类中所有的属性,不包括实例属性

②实例名.__dict__

效果:打印该实例的所有属性,不包括类属性

class Province(object):country = 'China'def __init__(self, name, count):self.name = nameself.count = countdef func(self, *args, **kwargs):print("func")p = Province("jiangsu",20000)  #实例化
print(p.__dict__) #实例名.__dict__#输出
{'count': 20000, 'name': 'jiangsu'}  #打印该实例的所有属性,不包括类属性

7 、__str__

说明:如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Province(object):country = 'China'def __init__(self, name):self.name = namedef __str__(self):return "<obj:{0}>".format(self.name)p = Province("jiangsu")
print(p)  #打印这个对象#输出
<obj:jiangsu>  #给对象重新起了一个名字

注:这个会在django框架里面会用到

8 、__getitem____setitem____delitem__

说明:用于索引操作,如字典。以上分别表示获取、设置、删除数据

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__函数中添加删除功能即可

9、__new__ \ __metaclass__

__new__概念

new方法是类自带的一个方法,可以重构,__new__方法在实例化的时候也会执行,并且先于__init__方法之前执行

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Foo(object):def __init__(self, name):self.name = nameprint("Foo __init__")def __new__(cls, *args, **kwargs):print("Foo __new__", cls, *args, **kwargs)return object.__new__(cls)f = Foo("shuaigaogao")# 输出
Foo __new__ <class '__main__.Foo'> shuaigaogao
Foo __init__

__new__方法作用

作用:所有对象都是通过new方法来实例化的,new里面调用了init方法,所以在实例化的过程中先执行的是new方法,而不是init方法。

①重构__new__方法

class Foo(object):def __init__(self,name):self.name = nameprint("Foo __init__")def __new__(cls, *args, **kwargs):print("Foo __new__",cls, *args, **kwargs)f = Foo("shuaigaogao")  #实例化#输出
Foo __new__ <class '__main__.Foo'> shuaigaogao

由上面的例子看出,没有执行__init__方法

②重构__new__方法,并继承父类的__new__方法

class Foo(object):def __init__(self,name):self.name = nameprint("Foo __init__")def __new__(cls, *args, **kwargs):   #cls相当于传入类Fooprint("Foo __new__",cls, *args, **kwargs)return object.__new__(cls)  #继承父类的__new__方法,这边必须以返回值的形式继承f = Foo("shuaigaogao")#输出
Foo __new__ <class '__main__.Foo'> shuaigaogao

由上面不难看出,大多数情况下,你都不要去重构你的__new__方法,因为你父类中已经有__new__方法了,已经帮你写好了怎么去创建类,如果你重写的话,就会覆盖父类的里面的__new__方法。但是你重构可以增加一点小功能,但是你覆盖了以后还是需要继承父类回来,要不然你的这个实力就创建不了。

__new__使用场景

我想对我自己写的一些类进行定制,就在它实例化之前就进行定制,就可以用到__new__方法,new方法就是用来创建实力的,重构new方法,必须以返回值的形式继承父类的new方法。

在创建对象时候,同时创建一个类变量

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:778463939
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Foo(object):def __init__(self,name):self.name = nameprint("Foo __init__")def __new__(cls, *args, **kwargs):  #cls相当于是传入的类名Foocls.name = "shuaigaogao"  #创建对象是定义静态变量print(cls.name)return object.__new__(cls)  #继承父类的__new__方法f = Foo("shuaigaogao")
print(Foo.name)#输出
shuaigaogao
Foo __init__
shuaigaogao

__metaclass__

metaclass这个属性叫做元类,它是用来表示这个类是由谁来帮他实例化创建的,说白了,就是相当于自己定制一个类。

class MyType(type):def __init__(self,*args,**kwargs):print("Mytype __init__",*args,**kwargs)def __call__(self, *args, **kwargs):print("Mytype __call__", *args, **kwargs)obj = self.__new__(self)print("obj ",obj,*args, **kwargs)print(self)self.__init__(obj,*args, **kwargs)return objdef __new__(cls, *args, **kwargs):print("Mytype __new__",*args,**kwargs)return type.__new__(cls, *args, **kwargs)class Foo(object,metaclass=MyType):  #python3统一用这种#__metaclass__ = MyType  #python2.7中的写法def __init__(self,name):self.name = nameprint("Foo __init__")def __new__(cls, *args, **kwargs):print("Foo __new__",cls, *args, **kwargs)return object.__new__(cls)f = Foo("shuaigaogao")
print("f",f)
print("fname",f.name)#输出
Mytype __new__ Foo (<class 'object'>,) {'__new__': <function Foo.__new__ at 0x0000025EF0EFD6A8>,
'__init__': <function Foo.__init__ at 0x0000025EF0EFD620>, '__qualname__': 'Foo', '__module__': '__main__'}
Mytype __init__ Foo (<class 'object'>,) {'__new__': <function Foo.__new__ at 0x0000025EF0EFD6A8>,'__init__': <function Foo.__init__ at 0x0000025EF0EFD620>, '__qualname__': 'Foo', '__module__': '__main__'}
Mytype __call__ shuaigaogao
Foo __new__ <class '__main__.Foo'>
obj  <__main__.Foo object at 0x0000025EF0F05048> shuaigaogao
<class '__main__.Foo'>
Foo __init__
f <__main__.Foo object at 0x0000025EF0F05048>
fname shuaigaogao

创建过程如下:

类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__

python教程:类的装饰器方法、特殊成员方法相关推荐

  1. python 元类与装饰器

    直接上代码 元类 metaclass class MyType(type):def __init__(self, *args, **kwargs):print("MyType.__init_ ...

  2. 廖雪峰python教程笔记:装饰器

    这是看廖老师python教程的第一个的笔记,因为这是这份教程最难的章节之一,我来来回回看了三遍,终于有所突破,写在这里是为了巩固自己的理解,同时也是希望有错的地方能够得到指正.具体内容见廖雪峰老师的课 ...

  3. 廖雪峰python教程学习:装饰器@小结

    装饰器@小结 廖雪峰老师的python教程 在代码运行期间动态增加功能的方式,称为装饰器 本质上,装饰器是一个可以返回函数的高阶函数 最基本的可以定义如下: def log(func):@functo ...

  4. 初学者python笔记(类的装饰器、property方法、元类)

    文章目录 上下文协议管理 类的装饰器基本原理 property方法的巧用 利用描述符自定制property property下的setter与deleter Python的元类 元类的概念 自定义元类 ...

  5. python闭包函数使用教程_Python闭包装饰器使用方法汇总

    闭包内容: 匿名函数:能够完成简单的功能,传递这个函数的引用,只有功能 普通函数:能够完成复杂的功能,传递这个函数的引用,只有功能 闭包:能够完成较为复杂的功能,传递这个闭包中的函数以及数据,因此传递 ...

  6. python基础教程:函数装饰器详解

    谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函数 方法 类 基础:函数装饰器的表现方式 假如你已经定义了一个函数fu ...

  7. 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解

    第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一.    引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...

  8. Python中的decorator装饰器使用方法

    装饰器的运用是Python编程中的一项高级技巧,这里由浅入深,整理了12步入门Python中的decorator装饰器使用方法,需要的朋友可以参考下 装饰器(decorator)是一种高级Python ...

  9. python 类的使用(5)之类装饰器(类的装饰器和类作为装饰器)

    在阅读博客中,发现了类装饰器的存在,由于之前就在写类相关的专栏,这次就赶紧补上之前的内容啦.类装饰器这个词是有歧义的,因为类本身可以作为装饰器,一个类也可以被函数装饰器所装饰.今天就简单介绍一下这两种 ...

最新文章

  1. python中的模块如何学习_在python中学习队列模块(如何运行它)
  2. [9.28模拟] good
  3. php 360 极速模式,如何让360浏览器默认使用极速模式
  4. GLSL实现滤镜效果
  5. 联想电脑的一键换机软件——乐换机
  6. Jmeter(二十二)_jenkins配置gitlab插件与ant插件
  7. php 清空一个数组_PHP工程师学Python数据类型
  8. HNU 程序设计 飞机起飞时间安排
  9. HTML中的图像和链接
  10. excel甘特图模板_项目管理工具之甘特图使用流程
  11. 图像下采样 matlab_MATLAB--数字图像处理 图像的采样与量化
  12. 分布式事务 java代码_Java分布式事务概念与实现示例
  13. r语言boxcox异方差_R教程-15:线性回归中的异方差
  14. ISACA最新高薪认证 | CDPSE数据隐私解决方案工程师
  15. Kryo工具类 序列化和反序列化操作工具类KryoUtils
  16. Kotlin Android Extensions使用指南
  17. iOS LeetCode ☞ 找到字符串中所有字母异位词
  18. Boot启动报错,版本不符合
  19. 基于Python的名片管理系统
  20. 【部署】NIDS之SNORT部署

热门文章

  1. PHP7 学习笔记(六)403 Forbidden - WAMP Server 2.5
  2. Hyper-V 2016 系列教程48 Windows Server Backup 一次性备份操作
  3. 大数据治理需要具备哪些能力和关键技术?
  4. Mysql 内部结构 / Replication | 层次结构
  5. 孙钟秀--《操作系统教程》注释(陈怀临)-- 读书笔记
  6. CentOS 6.3下Samba服务器的安装与配置(转)
  7. 联想T430i安装Win7
  8. 【学习笔记】27、面向对象学习
  9. 【PP生产订单】收货Goods Receipt
  10. 【推荐】会开发和懂开发的区别