property
官方定义: @property
的作用是在新式类中返回属性值。
有啥用?功能 :
- 简单说:就是把类里的 实例方法 当做 属性 去 调用/使用.使封装性更好 , 让开发者在使用的时候,就像是在调用属性一样简单 .
@property 的使用:
举例:
class C(object):
def __init__(self):
self._x = 'name'
@property
def say_name(self):
print(self._x, 'say_name执行...')
@say_name.setter
def say_name(self, value):
self._x = value
@say_name.deleter
def say_name(self):
del self._x
# 创建对象c
c = C()
# 打印调用c.x的结果 调用时自动调用say_name方法
c.say_name
# 修改x的值 自动调用x.setter
c.say_name = '年龄'
c.say_name
# # 删除 时自动调用x.deleter
del c.say_name
使用@property
装饰器 注意被装饰的方法的名字,用他(say_name)去调用setter和 delete , 然后函数名用一个函数名 这样就联系起来了(格式)
描述符
1.property 就是一个描述符 , 现成的 , 功能已经做好了.可以直接使用
2 .在开发中 , 想要用@property
这种形式,可以自己定义一个描述符.
自定义描述符有两种方式 :
方式1:描述符当作类属性
# 方式1 : 描述符放到类属性的位置
class MyDescriport():
def __init__(self):
print('MyDescriport __init__执行中')
def __get__(self, instance, owner):
print('get called')
return 'get'
def __set__(self, instance, value):
print('set called')
def __delete__(self, instance):
print('delete called')
class Foo():
# 描述符
attr = MyDescriport()
def __int__(self):
print('Foo init执行中...')
f = Foo() # 创建f对象
f.attr # 自动调用get
f.attr = 100 # 自动调用get
描述符给我们最后的现象是 : 像在操作属性一样
方式2:
自定义描述符 , 只要类中至少存在__get__
__set__
__delete__
其一 那这个类就是描述符
这里解释下__get__(self, instance, owner)中的三个参数:
self
:描述符对象自身instance
:被代理类的实例对象owner
:将描述符对象附加到哪个类上,其实是instance所属的类,也就是type
# 方式2:用装饰器的方式
class MyDescriptor:
def __init__(self, func):
print("--MyDescriptor init方法--")
self.__func = func
def __get__(self, instance, owner):
print('get called')
return self.__func(instance)
# return 'get'
def __set__(self, instance, value):
print('set called')
def __delete__(self, instance):
print('delete called')
class Foo:
@MyDescriptor # 相当于 print_test = MyDescriptor(print_test)
def print_test(self):
print("print_test方法, 执行中...")
return 100
f = Foo() # 创建f对象 , 21行代码会自己先运行 因为MyDescriptor(print_test) 这是在创建对象 ,
# print_test的地址引用 被当作参数传到了 MyDescriptor 类中 ,
# MyDescriptor 的 __init__执行 , 并保存了最开始的print_test函数的引用到自己的属性里 __func
print(f.print_test) # 调用 print_test时 , MyDescriptor 的 __get__ 会执行 ,
#self.__func(instance) 相当于 print_test(self) 执行了 然后返回100
都写在注释上了