类的装饰器方法、特殊成员方法

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

说明:表示类的描述信息


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__

说明:

  1. __module__: 表示当前操作的对象在哪个模块
  2. __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)

 

= Foo()   #执行__init__

f(1,2,3,name=333)  # 执行call方法,也可以写成 Foo()(1,2,3,name=333)

 

#输出

running call (123) {‘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")

 

= 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)

 

= 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)

 

 

= Foo()

f["name"= "shuaigaogao"  #自动触发__setitem__方法

f["name"]      #自动触发__getitem__方法

del f["name"]  #自动触发__delitem__方法

 

#输出

__setitem__: name shuaigaogao

__getitem__: name

__delitem__ name

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

9、__new__ \ __metaclass__

详细说明:点击

原文地址:https://www.cnblogs.com/fengff/p/9419155.html

时间: 2024-11-05 19:01:44

类的装饰器方法、特殊成员方法的相关文章

【python】-- 类的装饰器方法、特殊成员方法

装饰器方法 类的另外的特性,装饰器方法:静态方法(staticmethod).类方法(classmethod).属性方法(property) 一.静态方法 在方法名前加上@staticmethod装饰器,表示此方法为静态方法 class Dog(object): def __init__(self,name): self.name = name @staticmethod #在方法前加上staticmethod 装饰器定义静态方法 def eat(): print("dog is eating&

用类作为装饰器装饰函数!

在python中我们可以利用一个函数作为装饰器来装饰另一个函数,但是装饰器只能是函数吗 ?当然了我们还可以使用类来作为装饰器! class A(object): def __init__(self,func): print('定义初始化函数') print('func name is %s'%func.__name__) self.__func = func def __call__(self): print('call 方法作为装起中的功能') self.__func() print('增加的

Python之旅的第28天(描述符、类的装饰器)

周末真好,时间充裕,都能按照要求自己练习,感觉就是好 一.描述符 上次针对描述符的内容,理解的非常不到位,所以我就特地找了新的内容好好看了看,总结一下就是下面这些 # 前天我大概知道类描述符的一些特性,以及什么是数据描述符和非数据描述符 # 今天白天没事琢磨了一下,顺便又看了看各种案例,貌似理解更深入了一些 # 数据描述符:就是这个类属性是由一个实现了__get__(),__set__(),__delete__()中方法的新式类搞定了 # 非数据描述符则是,没有__set__方法的 # 当时没有

python装饰器方法

前几天向几位新同事介绍项目,被问起了@login_required的实现,我说这是django框架提供的装饰器方法,验证用户是否登录,只要这样用就行了,因为自己不熟,并没有做过多解释. 今天查看django官网,忽然发现,装饰器用法并不是django框架提供的,而是python的一种语法,真心汗一个,自以为python用的很熟了,看来是井底之蛙! 恰逢周末,静下心来了解一下python的装饰器方法. 谈到代码里的装饰器,很自然的想到了设计模式中的装饰器模式,为了防止再次张冠李戴,特意翻了翻设计模

Python进阶-----类的装饰器及应用

回顾什么是装饰器: 装饰器定义:本质就是函数(高阶函数),功能是为其他函数(对象)添加新功能 一.类的装饰器基本实现原理如下: 1 def deco(cls): 2 print('类的装饰器=========>') 3 print('='*20) 4 return cls 5 6 @deco #====> Foo = deco(Foo) 7 class Foo: 8 pass 二.上述的简单装饰器是没有参数的,现在我们加上参数 1 def cls_decorator(**kwargs): #支

19 描述符应用 与类的装饰器

上下文管理协议 class Open: def __init__(self,name): self.name = name def __enter__(self): print('执行enter') def __exit__(self, exc_type, exc_val, exc_tb): print('执行exit') with Open('a.txt') as f: print(f) print('______') print('00000') with open 执行了enter f为e

python描述符、property、函数(类)装饰器实例解析

1 import sys 2 3 ''' 4 当使用实例对象访问属性时,都会调用__getattribute__内建函数 5 __getattribute__查找属性的优先级 6 1.类属性 7 2.数据描述符 8 3.实例属性 9 4.非数据描述符 10 5.__getattr__() 11 12 #实例.属性 13 c.x ==>type(x).__dict__['x'].__get__(x,type(x)) 14 #类.属性 15 C.x ==>X.__dict__['x'].__get

python__高级 : 类当作装饰器

类在创建对象时,会调用 __init__ 初始化一些东西 , 然后 如果类中定义了 __call__ 方法,可以直接用  对象()  这种方法调用,所以可以用类来装饰函数: class Test(object): def __init__(self, func): print('----装饰-----') print('func name is %s' % func.__name__) self.__func = func def __call__(self, *args, **kwargs):

python - 用类写装饰器

这里用到了__call__的class内置参数 #类装饰器: class zsq(): #本质是定义一个参数,让装饰的主题传递至__call__方法内部 def __init__(self,obj): self.obj = obj #利用__call__将类转变为可执行 #__call__内相当于函数装饰器最外层 def __call__(self, *args, **kwargs): print("start") #返回主机函数 re = self.obj(*args, **kwar