• python内置装饰器---- @property


    最近看Robotframe中SeleniumLibrary 源码,发现源代码中存在许多@property,因此看下python中内置的装饰器。
    简言之,python 内置的装饰器常见为3个 ,分别为@property 、@classmethod和@staticmethod。

    property 源码分析

    查看property定义 class property(fget=None, fset=None, fdel=None, doc=None) ,说明property是一个类,包含3个可调用参数,和一个str的参数。返回为一个 property 属性。

    
    class property(object):
       def __init__(self, fget: Optional[Callable[[Any], Any]] = ...,
                    fset: Optional[Callable[[Any, Any], None]] = ...,
                    fdel: Optional[Callable[[Any], None]] = ...,
                    doc: Optional[str] = ...) -> None: ...
       def getter(self, fget: Callable[[Any], Any]) -> property: ...
       def setter(self, fset: Callable[[Any, Any], None]) -> property: ...
       def deleter(self, fdel: Callable[[Any], None]) -> property: ...
       def __get__(self, obj: Any, type: Optional[type] = ...) -> Any: ...
       def __set__(self, obj: Any, value: Any) -> None: ...
       def __delete__(self, obj: Any) -> None: ...
       def fget(self) -> Any: ...
       def fset(self, value: Any) -> None: ...
       def fdel(self) -> None: ...
    
    

    采用测试代码 python 版本为3.5.2

    class C:
        def __init__(self):
            self._x = None
    
        def getx(self):
            return self._x
    
        def setx(self, value):
            self._x = value
    
        def delx(self):
            del self._x
    
    test = C()
    x = property(test.getx,test.setx,test.delx,"I'm the 'x' property.")
    test.x = 5
    print(test.x)
    del test.x
    
    

    通过x = property(test.getx,test.setx,test.delx,"I'm the 'x' property.") 将x变更为类对象test的属性,可以对其进行 赋值 删除等操作。

    property 作为装饰器应用

    先看下面代码

    class number(object):
       def __init__(self):
           self._x = 1000
       
       # @property
       def get_x(self):
           return self._x
    
    test = number()
    print(test.get_x())
    

    在方法未添加装饰器前,get_x是一个可以修改的类的方法。而添加 @property装饰器后,get_x 从类的方法变更为类属性,从而调用方式也发生变化。
    在之前的源代码分析中,property可以传入三个参数,前面的装饰器只装饰了一个函数,可以采用以下方式进行装饰三个函数

    
    class C:
       def __init__(self):
           self._x = None
    
       @property
       def x(self):
           """I'm the 'x' property."""
           return self._x
    
       @x.setter
       def x(self, value):
           self._x = value
    
       @x.deleter
       def x(self):
           del self._x
    test = C()
    test.x = 5
    print(test.x)
    
    

    可以看出这与源码中的结果是一样的,实际上 源码中的代码 属于 装饰器的另一种调用方法。

    小结

    property 本身上就是采用类方式实现的装饰器,若在类内部使用,则将类中定义的方法转换为类的属性,且将对类属性的赋值、删除操作变得和变量操作一样,
    可以说实现了多态。建议采用@property 装饰器的调用方法。应用方式

    • 单一装饰 直接采用@property 此装饰器 相当于调用fget, 将类中的方法装换为类属性
    • 进一步装饰 @x.setter 、 @x.deleter 将类方法变更为属性,且对属性进行 赋值和删除操作。
  • 相关阅读:
    linux系统安装过程记录
    Core WebAPI 部署问题
    Linux提示找不到ll命令的解决方法
    Deepin系统编辑新建文档菜单
    phpexcel多sheet分页设置背景色问题
    使用phpexcel时太多问题,建议使用PhpSpreadsheet
    QtBrowser浏览器
    git 查看某一行代码的修改历史
    PHPExcel设置打印区域
    scp 把linux上文件复制到本地报错
  • 原文地址:https://www.cnblogs.com/Finding-bugs/p/14176672.html
Copyright © 2020-2023  润新知