Python的property属性

2020-08-15  本文已影响0人  李白开水

简介

如果一个类使用了@property装饰器,并且这个方法只接收一个self参数,而且这个方法还有一个返回值,那么这个方法就是这个类的property属性。

调用的时候把原来的调用方法改成了看上去是在调用一个属性。

class Goods:

    @property
    def foo(self):
        return 100

good = Goods()
print(good.foo) 

运行:

D:\test>python property01.py
100

这样做可读性更高,把复杂的过程封装到一个方法中,使用的时候很简单,而且不用考虑传递参数的问题。

创建property属性的方式

方式1:装饰器

在Python2中,如果一个类不继承object类,这样的类叫做经典类,经典类只有上述一种使用property的方法。

如果这个类继承了object类,有三种方法可以使用property。(python3中所有的类都继承了object,不管代码写没写继承object)这三种方法是@property@方法名.setter@方法名.deleter

使用方法如下:

class Goods:

    @property
    def price(self):
        print("@property")
        return 100

    @price.setter
    def price(self, value):
        print('@price.setter')

    @price.deleter
    def price(self):
        print('@price.deleter')

good = Goods()
print(good.price)
good.price = 123
del good.price

good.price语句会调用@property装饰的方法,good.price = 123会调用@price.setter装饰的方法,del good.price会调用@price.deleter装饰的方法。

运行结果如下:

D:\test>python property01.py
@property
100
@price.setter
@price.deleter

也就是说,setter可以用来设置这个属性的值,所以它要接收一个除了self的参数,deler用来删除属性。

这三个方法的方法名相同。

方式2:类属性

先定义一个类和方法,然后再定义一个类属性,把property(方法名)赋给类属性。

使用的时候,创建了实例对象之后,用实例对象名.类属性即可。

例如:

class Foo:
    def get_bar(self):
        return '123456'

    BAR = property(get_bar)

foo = Foo()
print(foo.BAR)

运行:

D:\test>python property02.py
123456

这时候property可以接收四个参数,可以在ipython中用help(property)来查看:

class property(object)
 |  property(fget=None, fset=None, fdel=None, doc=None)
 |
 |  Property attribute.
 |
 |    fget
 |      function to be used for getting an attribute value
 |    fset
 |      function to be used for setting an attribute value
 |    fdel
 |      function to be used for del'ing an attribute
 |    doc
 |      docstring
 |
 |  Typical use is to define a managed attribute x:
 |
 |  class C(object):
 |      def getx(self): return self._x
 |      def setx(self, value): self._x = value
 |      def delx(self): del self._x
 |      x = property(getx, setx, delx, "I'm the 'x' property.")
 |
 |  Decorators make defining new properties or modifying existing ones easy:
 |
 |  class C(object):
 |      @property
 |      def x(self):
 |          "I am the 'x' property."
 |          return self._x
 |      @x.setter
 |      def x(self, value):
 |          self._x = value
 |      @x.deleter
 |      def x(self):
 |          del self._x
 |
 |  Methods defined here:
 |
 |  __delete__(self, instance, /)
 |      Delete an attribute of instance.
 |
 |  __get__(self, instance, owner, /)
 |      Return an attribute of instance, which is of type owner.
 |
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |
 |  __set__(self, instance, value, /)
 |      Set an attribute of instance to value.
 |
 |  deleter(...)
 |      Descriptor to change the deleter on a property.
 |
 |  getter(...)
 |      Descriptor to change the getter on a property.
 |
 |  setter(...)
 |      Descriptor to change the setter on a property.
 |
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  __isabstractmethod__
 |
 |  fdel
 |
 |  fget
 |
 |  fset

property接收的参数:

property(fget=None, fset=None, fdel=None, doc=None)

第一个参数是方法名,调用实例对象.属性时,会自动执行方法。

第二个参数是设置属性的值,第三个参数是删除属性,第四个参数是字符串,这个参数是这个属性的描述信息,可以调用实例对象名.属性.__doc__查看。

例如:

class Foo:
    def get_bar(self):
        print("get")
        return 123456

    def set_bar(self, value):
        print("set")
        return value

    def del_bar(self):
        print("del")
        return "hahaha"

    BAR = property(get_bar, set_bar, del_bar)

foo = Foo()
print(foo.BAR)
foo.BAR = 778899
print(foo.BAR)
# print(foo.BAR.__doc__)
del foo.BAR

运行:

D:\test>python property02.py
get
123456
set
get
123456
del
上一篇下一篇

猜你喜欢

热点阅读