zoukankan      html  css  js  c++  java
  • 类的装饰器方法、特殊成员方法

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

     View Code

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

     View Code

    3、删除转变的静态属性

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

     View Code

     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. 静态方法是访问不了类或实例中的任何属性,它已经脱离了类,一般会用在一些工具包中
    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__

     详细说明:点击

  • 相关阅读:
    错误及异常处理-[PathTooLongException]指定的路径或文件名太长
    在线颜色转换器
    文件被锁定的原因
    EF6官方文档
    我关注的
    "此实现不是 Windows 平台 FIPS 验证的加密算法的一部分"解决办法
    Rsync Error set gid failed rsync error
    转载——EntiyFrameWork教程
    Word 出现“因为没有打开的文档,所以这一命令无效”的错误
    Winsock网络编程笔记:基于UDP的Client
  • 原文地址:https://www.cnblogs.com/fengff/p/9419155.html
Copyright © 2011-2022 走看看