装饰器方法

类的另外的特性,装饰器方法:静态方法(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(属性装饰器)去装饰方法,来给转换后的静态属性赋值

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 = food d = 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 = name
self.__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 = food d = Dog("shabihong")
d.eat #第一份赋值的是None
d.eat = "hotdog"
d.eat #第二个赋值是hotdog #输出
shabihong is eating None
set to food: hotdog
shabihong is eating hotdog #说明赋值成功

3、删除转变的静态属性

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

class Dog(object):

    def __init__(self,name):
self.name = name
self.__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 = food @eat.deleter #定义可以删除eat这个静态属性
def eat(self):
del self.__food
print("food 变量删除完毕") d = Dog("shabihong")
del d.eat #删除静态属性eat #输出
food 变量删除完毕

 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("\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__

说明:表示类的描述信息

class Dog(object):
"""此类是形容Dog这个类""" #类的描述信息 def __init__(self,name):
self.name = name print(Dog.__doc__) #打印类的描述信息 #输出
此类是形容Dog这个类

2、 __module__和__class__

说明:

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

aa.py的代码:

class C(object):

    def __init__(self):
self.name = "shuaigaogao"

index.py的代码:

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__

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

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__

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

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__

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

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__方法,那么在打印 对象 时,默认输出该方法的返回值

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__

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

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__

详细说明:点击

【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学习之输入,输出流

    输入流与输出流 1,流的分类:字节流和字符流 区别如下: 1,字节流(8位Unicode)在操作的时候本身是不会用到缓冲区(内存)的byte,是与文件本身直接操作的,而字符流(16位Unicode)在 ...

  2. sass高级语法的补充

    1. 继承 2.混入 3.函数 我这篇博客需要点基础才能看懂, 但我这篇博客是对上一篇的 sass高级语法 的补充 从这方面来看也无所谓了

  3. Transportation poj1040

    Ruratania is just entering capitalism and is establishing new enterprising activities in many fields ...

  4. Angular 学习笔记——run

    <!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <met ...

  5. Tomcat、Weblogic、JBoss、GlassFish、Resin、Websphere弱口令及拿webshell方法总结 [复制链接]

    1.java应用服务器    Java应用服务器主要为应用程序提供运行环境,为组件提供服务.Java 的应用服务器很多,从功能上分为两类:JSP 服务器和 Java EE 服务器.1.1  常见的Se ...

  6. 谁动了我的cpu——oprofile使用札记(转)

    引言 cpu无端占用高?应用程序响应慢?苦于没有分析的工具? oprofile利用cpu硬件层面提供的性能计数器(performance counter),通过计数采样,帮助我们从进程.函数.代码层面 ...

  7. php 处理 form 表单提交多个 name 属性值相同的 input 标签

    一 问题 在公司的开发过程中,遇到了一个问题:如何处理 form 表单提交了多个 name 属性值相同的 input 标签?源码如下(源码是在 form 表单之中的): <!--{loop $a ...

  8. 给UITextField设置头或尾空白

    有时候,我们需要在UITextField的头尾加入一些空白,如下图所示: 其中,黄色和红色部分代表空白. 实现起来,比较简单,只需要设置UITextField的leftView.leftViewMod ...

  9. Asp.net MVC 插件式应用框架

    Asp.net MVC 插件式应用框架 2013年05月13日 10:16供稿中心: 互联网运营部 摘要:这几年来做了很多个网站系统,一直坚持使用asp.net mvc建站,每次都从头开始做Layou ...

  10. URL检测脚本

    #!/bin/bash# filename : 8_5_1.sh function usage(){ echo "usage:$0 url" exit 1} function ch ...