装饰器方法

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

一、静态方法

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

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

静态方法特性

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

1、静态方法,是不可以传入self参数的,但是想传也可以,调用时必须传入实例本身

  1. class Dog(object):
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5.  
  6. @staticmethod #定义静态方法
  7. def eat(self,food): #可以定义,但是需传入实例本身
  8. print("{0} is eating {1}".format(self.name,food))
  9.  
  10. d = Dog("shabi")
  11. d.eat(d,"hotdog") #传入实例d本身,否则会报错
  12.  
  13. #输出
  14. shabi is eating hotdog

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

  1. class Dog(object):
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5.  
  6. @staticmethod
  7. def eat(food):
  8. print("is eating {0}".format(food))
  9.  
  10. Dog.eat("hotdog")
  11.  
  12. #输出
  13. is eating hotdog

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

  1. import os
  2.  
  3. os.system()
  4. os.mkdir()

二、类方法

在方法名前加上@classmethod装饰器,表示此方法为类方法

  1. class Dog(object):
  2.  
  3. name = "honggege" #定义静态属性
  4. def __init__(self,name):
  5. self.name = name
  6.  
  7. @classmethod #定义类方法
  8. def eat(self,food):
  9. print("{0} is eating {1}".format(self.name,food))

 类方法特性

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

1、访问实例变量

  1. class Dog(object):
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5.  
  6. @classmethod #定义类方法
  7. def eat(self,food):
  8. print("{0} is eating {1}".format(self.name,food))
  9.  
  10. d = Dog("shabihong")
  11. d.eat("hotdog")
  12.  
  13. #输出
  14. File "D:/PycharmProjects/pyhomework/day7/类方法.py", line 11, in <module>
  15. d.eat("hotdog")
  16. File "D:/PycharmProjects/pyhomework/day7/类方法.py", line 8, in eat
  17. print("{0} is eating {1}".format(self.name,food))
  18. AttributeError: type object 'Dog' has no attribute 'name'

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

  1. class Dog(object):
  2.  
  3. name = "honggege" #定义类变量
  4. def __init__(self,name):
  5. self.name = name
  6.  
  7. @classmethod
  8. def eat(self,food):
  9. print("{0} is eating {1}".format(self.name,food))
  10.  
  11. d = Dog("shabihong")
  12. d.eat("hotdog")
  13.  
  14. #输出
  15. honggege is eating hotdog #调用的是类变量

3、使用场景:一般是需要去访问写死的变量,才会用到类方法装饰器

三、属性方法

在方法名前加上@property装饰器,表示此方法为属性方法

  1. class Dog(object):
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5.  
  6. @property #定义属性方法
  7. def eat(self):
  8. print("{0} is eating".format(self.name))

属性方法特性

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

1、静态属性的调用

  1. class Dog(object):
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5.  
  6. @property #定义属性方法
  7. def eat(self):
  8. print("{0} is eating".format(self.name))
  9.  
  10. d = Dog("shabihong")
  11. d.eat #把方法变成静态属性调用
  12.  
  13. #输出
  14. shabihong is eating

 2、给转成的静态属性赋值

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

  1. class Dog(object):
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5.  
  6. @property #定义属性方法
  7. def eat(self):
  8. print("{0} is eating {1}".format(self.name,"honggege"))
  9.  
  10. @eat.setter #定义一个可以传参的方法
  11. def eat(self,food):
  12. print("set to food:",food)
  13. # self.__food = food
  14.  
  15. d = Dog("shabihong")
  16. d.eat = "hotdog" #给转成的静态变量赋值
  17. d.eat
  18.  
  19. #输出
  20. set to food: hotdog
  21. shabihong is eating honggege

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

  1. class Dog(object):
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5. self.__food = None
  6.  
  7. @property #定义属性方法
  8. def eat(self):
  9. print("{0} is eating {1}".format(self.name,self.__food))
  10.  
  11. @eat.setter #定义可以设置变量赋值
  12. def eat(self,food):
  13. print("set to food:",food)
  14. self.__food = food
  15.  
  16. d = Dog("shabihong")
  17. d.eat #第一份赋值的是None
  18. d.eat = "hotdog"
  19. d.eat #第二个赋值是hotdog
  20.  
  21. #输出
  22. shabihong is eating None
  23. set to food: hotdog
  24. shabihong is eating hotdog #说明赋值成功

3、删除转变的静态属性

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

  1. class Dog(object):
  2.  
  3. def __init__(self,name):
  4. self.name = name
  5. self.__food = None
  6.  
  7. @property
  8. def eat(self):
  9. print("{0} is eating {1}".format(self.name,self.__food))
  10.  
  11. @eat.setter
  12. def eat(self,food):
  13. print("set to food:",food)
  14. self.__food = food
  15.  
  16. @eat.deleter #定义可以删除eat这个静态属性
  17. def eat(self):
  18. del self.__food
  19. print("food 变量删除完毕")
  20.  
  21. d = Dog("shabihong")
  22. del d.eat #删除静态属性eat
  23.  
  24. #输出
  25. food 变量删除完毕

 4、静态属性使用场景

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

  1. 连接航空公司API查询

  2. 对查询结果进行解析

  3. 返回结果给你的用户

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

  1. class Flight(object):
  2. def __init__(self,name):
  3. self.flight_name = name
  4.  
  5. def checking_status(self):
  6. print("checking flight %s status " % self.flight_name)
  7. return 1
  8.  
  9. @property
  10. def flight_status(self):
  11. status = self.checking_status()
  12. if status == 0 :
  13. print("flight got canceled...")
  14. elif status == 1 :
  15. print("flight is arrived...")
  16. elif status == 2:
  17. print("flight has departured already...")
  18. else:
  19. print("cannot confirm the flight status...,please check later")
  20.  
  21. @flight_status.setter #修改
  22. def flight_status(self,status):
  23. status_dic = {
  24. 0 : "canceled",
  25. 1 :"arrived",
  26. 2 : "departured"
  27. }
  28. print("\033[31;1mHas changed the flight status to \033[0m",status_dic.get(status) )
  29.  
  30. @flight_status.deleter #删除
  31. def flight_status(self):
  32. print("status got removed...")
  33.  
  34. f = Flight("CA980")
  35. f.flight_status
  36. f.flight_status = 2 #触发@flight_status.setter
  37. del f.flight_status #触发@flight_status.deleter

装饰器方法总结:

  1. 静态方法是访问不了类或实例中的任何属性,它已经脱离了类,一般会用在一些工具包中
  2. 类方法,只能访问类变量,不能访问实例变量
  3. 属性方法是把一个方法变成一个静态属性

类的特殊成员方法

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

1、 __doc__

说明:表示类的描述信息

  1. class Dog(object):
  2. """此类是形容Dog这个类""" #类的描述信息
  3.  
  4. def __init__(self,name):
  5. self.name = name
  6.  
  7. print(Dog.__doc__) #打印类的描述信息
  8.  
  9. #输出
  10. 此类是形容Dog这个类

2、 __module__和__class__

说明:

  1. __module__: 表示当前操作的对象在哪个模块
  2. __class__:表示当前操作的对象的类是什么

aa.py的代码:

  1. class C(object):
  2.  
  3. def __init__(self):
  4. self.name = "shuaigaogao"

index.py的代码:

  1. from lib.aa import C
  2.  
  3. obj = C()
  4.  
  5. print(obj.__module__) #表示当前操作的对象在哪个模块
  6. print(obj.__class__) #表示当前操作的对象的类是什么
  7.  
  8. #输出
  9. lib.aa
  10. <class 'lib.aa.C'>

3 、__init__

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

4、 __del__

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

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,

所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的

5、 __call__

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

  1. class Foo(object):
  2. def __init__(self):
  3. self.name = "shuaigaogao"
  4.  
  5. def __call__(self, *args, **kwargs): #重写call方法
  6. print("running call",args,kwargs)
  7.  
  8. f = Foo() #执行__init__
  9. f(1,2,3,name=333) # 执行call方法,也可以写成 Foo()(1,2,3,name=333)
  10.  
  11. #输出
  12. running call (1, 2, 3) {'name': 333}

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

6 、__dict__

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

①类.__dict__

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

  1. class Province(object):
  2.  
  3. country = 'China'
  4.  
  5. def __init__(self, name, count):
  6. self.name = name
  7. self.count = count
  8.  
  9. def func(self, *args, **kwargs):
  10. print("func")
  11.  
  12. print(Province.__dict__) #类.__dict__
  13.  
  14. #输出
  15. {'__doc__': None, '__weakref__': <attribute '__weakref__' of 'Province' objects>, '__init__':
  16. <function Province.__init__ at 0x00000247F3CAD488>, 'country': 'China', '__dict__':
  17. <attribute '__dict__' of 'Province' objects>, 'func': <function Province.func at
  18. 0x00000247F3CAD510>, '__module__': '__main__'} #打印类中所有的属性,不包括实例属性

②实例名.__dict__

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

  1. class Province(object):
  2.  
  3. country = 'China'
  4.  
  5. def __init__(self, name, count):
  6. self.name = name
  7. self.count = count
  8.  
  9. def func(self, *args, **kwargs):
  10. print("func")
  11.  
  12. p = Province("jiangsu",20000) #实例化
  13. print(p.__dict__) #实例名.__dict__
  14.  
  15. #输出
  16. {'count': 20000, 'name': 'jiangsu'} #打印该实例的所有属性,不包括类属性

7 、__str__

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

  1. class Province(object):
  2.  
  3. country = 'China'
  4.  
  5. def __init__(self, name):
  6. self.name = name
  7.  
  8. def __str__(self):
  9. return "<obj:{0}>".format(self.name)
  10.  
  11. p = Province("jiangsu")
  12. print(p) #打印这个对象
  13.  
  14. #输出
  15. <obj:jiangsu> #给对象重新起了一个名字

注:这个以后会在django框架里面会用到,这边就不多说了

8 、__getitem__、__setitem__、__delitem__

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

  1. class Foo(object):
  2.  
  3. def __getitem__(self, key):
  4. print('__getitem__:',key)
  5.  
  6. def __setitem__(self, key, value):
  7. print('__setitem__:',key,value)
  8.  
  9. def __delitem__(self, key):
  10. print('__delitem__',key)
  11.  
  12. f = Foo()
  13. f["name"] = "shuaigaogao" #自动触发__setitem__方法
  14. f["name"] #自动触发__getitem__方法
  15. del f["name"] #自动触发__delitem__方法
  16.  
  17. #输出
  18. __setitem__: name shuaigaogao
  19. __getitem__: name
  20. __delitem__ name

注:这边的__delitem__没有做真正的删除,只是触发这个方法,想要真正删除,只需要在__delitem__函数中添加删除功能即可

9、__new__ \ __metaclass__

详细说明:点击

【python】-- 类的装饰器方法、特殊成员方法的更多相关文章

  1. 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法

    第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一.    案例说明 本节定义了类Sta ...

  2. python 类的装饰器

    我们知道,在不改变原有代码的基础上,我们可以使用装饰器为函数添加新的功能.同理,一切皆对象,我们也可以使用装饰器为类添加类属性.what? def deco(obj): obj.x = 1 obj.y ...

  3. python 类内部装饰器的实现 与 参数解构学习

    学习了函数的装饰器的写法,然后想到如果要在类中初始化或获取信息时能用装饰器做过滤和验证应该怎么写呢, 在网上查了下相关信息,感觉这样也是可以的,不知道会不会有什么问题class Ctj(): clas ...

  4. Python类中装饰器classmethod,staticmethod,property,

    @classmethod 有的时候在类中会有一种情况,就是这个方法并不需要使用每一个对象属性 因此 这个方法中的self参数一个完全无用的参数,使用classmethod class A: __cou ...

  5. python类常用装饰器

    class Myclass(object): def __init__(self): pass #必须实例化才能调用 def sayhi(self): print 'hello' #静态方法,跟类没什 ...

  6. python学习笔记--装饰器

    1.首先是一个很无聊的函数,实现了两个数的加法运算: def f(x,y): print x+y f(2,3) 输出结果也ok 5 2.可是这时候我们感觉输出结果太单一了点,想让代码的输出多一点看起来 ...

  7. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解

     1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...

  8. 11.python描述符---类的装饰器---@property

    描述符1.描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()这三个内置方法中的一个,描述符也被称为描述符协议(1):__ ...

  9. Python之路(第二十八篇) 面向对象进阶:类的装饰器、元类

    一.类的装饰器 类作为一个对象,也可以被装饰. 例子 def wrap(obj): print("装饰器-----") obj.x = 1 obj.y = 3 obj.z = 5 ...

随机推荐

  1. [转载]java自带线程池和队列详细讲解

    FROM:http://blog.csdn.net/sd0902/article/details/8395677 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中 ...

  2. Gentoo:startx出现Failed to load module问题

    安装完xorg-server后,startx启动桌面环境,出现缺少模块错误. 查看log: cat /var/log/Xorg.0.log | grep EE [75.403] (EE) Failed ...

  3. NGINX 缓存使用指南

    NGINX 缓存使用指南 [proxy_cache] Nginx 一个web缓存坐落于客户端和“原始服务器(origin server)”中间,它保留了所有可见内容的拷贝.如果一个客户端请求的内容在缓 ...

  4. oracle经常使用函数(1)

    1.返回与指定的字符相应的十进制数 select ascii('A') A,ascii('z') a,ascii('12') 一打,ascii(' ') kg from dual; 2.返回与指定十进 ...

  5. C#利用SharpZipLib解压或压缩文件(支持多层目录递归压缩)

    需要下载ICSharpCode.SharpZipLib.dll using System; using System.Collections.Generic; using System.Linq; u ...

  6. JS 手势长按代码

    同时支持长按和点击事件,无依赖版 <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  7. git删除所有历史提交记录,只留下最新的干净代码

    git删除所有历史提交记录,只留下最新的干净代码 1.Checkout git checkout --orphan latest_branch 2. Add all the files git add ...

  8. Android SDK环境搭建

    方法有二 方法一: Android SDK开发包国内下载地址 http://www.cnblogs.com/bjzhanghao/archive/2012/11/14/android-platform ...

  9. java.lang.IllegalArgumentException: Request header is too large的解决方法

    <Connector port="8080" protocol="HTTP/1.1"               connectionTimeout=&q ...

  10. 使用虚拟环境 virtualenv

    1.安装 $ sudo apt-get install python-virtualenv 2.重命名,一般虚拟环境会被命名为venv $ virtualenv   venv 3. 激活 $ sour ...