python笔记57-@property源码解读与使用

前言

Python 内置的 @property 装饰器的作用是把方法变成属性,调用的时候不需要加括号

property源码

property() 方法的传四个参数

  • fget —获取属性值的函数

  • fset —设置属性值的函数

  • fdel —删除属性值函数

  • doc —属性描述信息

class property(object):
"""
property(fget=None, fset=None, fdel=None, doc=None) -> property attribute

fget is a function to be used for getting an attribute value, and likewise
fset is a function for setting, and fdel a function for del'ing, an
attribute. 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
"""
def deleter(self, *args, **kwargs): # real signature unknown
""" Descriptor to change the deleter on a property. """
pass

def getter(self, *args, **kwargs): # real signature unknown
""" Descriptor to change the getter on a property. """
pass

def setter(self, *args, **kwargs): # real signature unknown
""" Descriptor to change the setter on a property. """
pass

def __delete__(self, *args, **kwargs): # real signature unknown
""" Delete an attribute of instance. """
pass

def __getattribute__(self, *args, **kwargs): # real signature unknown
""" Return getattr(self, name). """
pass

def __get__(self, *args, **kwargs): # real signature unknown
""" Return an attribute of instance, which is of type owner. """
pass

def __init__(self, fget=None, fset=None, fdel=None, doc=None): # known special case of property.__init__
"""
property(fget=None, fset=None, fdel=None, doc=None) -> property attribute

fget is a function to be used for getting an attribute value, and likewise
fset is a function for setting, and fdel a function for del'ing, an
attribute. 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

# (copied from class doc)
"""
pass

@staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass

def __set__(self, *args, **kwargs): # real signature unknown
""" Set an attribute of instance to value. """
pass

fdel = property(lambda self: object(), lambda self, v: None, lambda self: None) # default

fget = property(lambda self: object(), lambda self, v: None, lambda self: None) # default

fset = property(lambda self: object(), lambda self, v: None, lambda self: None) # default

__isabstractmethod__ = property(lambda self: object(), lambda self, v: None, lambda self: None) # default

源码解读

先看源码里面第一个示例

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.")

实例化后调用x属性

c = C()
c.x = 20 # c.x = value 将触发 setter
print(c.x) # c.x 将触发 getter
del c.x # del c.x 触发 deleter

c 是 C 的实例化对象, c.x 将触发 getter,c.x = value 将触发 setter , del c.x 触发 deleter。
如果给定 doc 参数,其将成为这个属性值的 docstring,否则 property 函数就会复制 fget 函数的 docstring(如果有的话)

装饰器使定义新属性或修改现有属性变得容易,property 的 getter, setter 和 deleter 方法同样可以用作装饰器:

class C(object):
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

这个代码和第一个例子完全相同,但要注意这些额外函数的名字和 property 下的一样,例如这里的 x。

@property 只读属性

我们知道类的属性是可以动态赋值的

class People(object):

def __init__(self):
self.name = "yoyo"
self.age = 20

people = People()
print(people.age) # 20
# 属性动态赋值
people.age = 22
print(people.age) # 22

如果我不想让age属性改变,可以使用 @property 可以设置只读属性的 getter 方法

class People(object):

def __init__(self):
self.name = "yoyo"
self.age = 20

@property
def get_age(self):
return 20

people = People()
print(people.get_age) # 20

如果使用这种赋值代码people.get_age = 22,会抛出异常AttributeError: can’t set attribute

使用示例

设置 my_age 属性可读可写

class Person(object):
def __init__(self, name, age):
self.__name = name
self.__age = age

@property
def my_age(self):
return self.__age

@my_age.setter
def my_age(self, value):
"""设置my_age属性,并校验值"""
if not isinstance(value, int):
raise ValueError('年龄必须是数字!')
if value < 0 or value > 100:
raise ValueError('年龄必须是0-100')
self.__age = value

person = Person("yoyo", 20)
print(person.my_age) # 20
person.my_age = 22
print(person.my_age) # 22
person.my_age = "hh" # ValueError: 年龄必须是数字!

如果你想设置my_age属性可以删除,需用到property 的 deleter 装饰器

2021年第八期《python接口web自动化+测试开发》7.17号开学(课程全面升级!) 加量不加价(新增postman, 赠送selenium和python基础2个课)

本期上课时间:7月17号-10月16号,每周六、周日晚上20:30-22:30

(0)

相关推荐

  • 面向对象编程(二)

    使用__slots__ 正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.先定义class: class Student ...

  • Python进阶:探秘描述符的工作原理

    作者:Magic Kaito 来源:水滴与银弹 在 Python 开发中,你可能听说过「描述符」这个概念,由于我们很少直接使用它,所以大部分开发人员并不了解它的原理. 但作为熟练使用 Python,想 ...

  • 神奇的Python property装饰器:1行代码让Python方法秒变属性

    神奇的Python property装饰器:1行代码让Python方法秒变属性

  • python语言线程标准库threading.local源码解读

    本段源码可以学习的地方: 1. 考虑到效率问题,可以通过上下文的机制,在属性被访问的时候临时构建: 2. 可以重写一些魔术方法,比如 __new__ 方法,在调用 object.__new__(cls ...

  • ASP.NET CORE 启动过程及源码解读

    在这个特殊的春节,大家想必都在家出不了们,远看已经到了回城里上班的日子,但是因为一只蝙蝠的原因导致我们无法回到工作岗位,大家可能有的在家远程办公,有些在家躺着看书,有的是在家打游戏:在这个特殊无聊的日 ...

  • 雨青的指标源码解读

    R1:=EMA(HHV(HIGH,500),21); R2:=EMA(HHV(HIGH,250),21); R3:=EMA(HHV(HIGH,90),21); R4:=EMA(LLV(LOW,500) ...

  • 建议收藏,22个Python迷你项目(附源码)

    在使用Python的过程中,我最喜欢的就是Python的各种第三方库,能够完成很多操作. 下面就给大家介绍22个通过Python构建的项目,以此来学习Python编程. 大家也可根据项目的目的及提示, ...

  • ASP.NET Core 5-Kestrel源码解读

    上节讲到了kestrel服务器的配置及使用,相信很多同学已经对kestrel服务器有了初步的了解,那么有的同学可能会想更加深入的了解一下Kestrel服务器的是怎么实现监听和接收http请求的,今天我 ...

  • PyTorch 源码解读之 torch.autograd

      磐创AI分享   来源 | GiantPandaCV 作者 | OpenMMLab 来源 | https://zhuanlan.zhihu.com/p/321449610 前言 本篇笔记以介绍 p ...

  • 22个Python迷你项目(附源码)

    在使用Python的过程中,我最喜欢的就是Python的各种第三方库,能够完成很多操作. 下面就给大家介绍22个通过Python构建的项目,以此来学习Python编程. 大家也可根据项目的目的及提示, ...

  • 超详细的 Bert 文本分类源码解读 | 附源码

    本文详细的GitHub地址: https://github.com/sherlcok314159/ML 接上一篇: 你所不知道的 Transformer! 参考论文 https://arxiv.org ...

  • PyTorch 源码解读之 BN & SyncBN

    目录1. BatchNorm 原理2. BatchNorm 的 PyTorch 实现2.1 _NormBase 类2.1.1 初始化2.1.2 模拟 BN forward2.1.3 running_m ...