什么是python描述符: 类里面有
__get__
或
__set__
或
__del__
的就叫描述符
属性查找优先级
- 类属性
-
数据描述符 (同时实现
__get__
和__set__
) - 实例属性
-
非数据描述符 (只实现
__get__
) -
__getattr__
通过代理和描述符实现属性懒加载
这里是使用装饰器的方式实现的懒加载。可以将耗时的操作放到方法里面。在未使用的时候是一个方法,当第一次使用过后就会替换掉方法,并为之设置属性值。
注意,只有在使用的时候才会执行函数里面的代码,并且只执行一次,再次使用的时候直接返回值
关键代码:
value
=
self
.
method
(
instance
)
setattr
(
instance
,
self
.
method_name
,
value
)
.
.
.
@LazyLoad
def
resource
(
self
)
:
代码如下:
from
functools
import
update_wrapper
class
LazyLoad
(
object
)
:
def
__init__
(
self
,
method
)
:
self
.
method
=
method
self
.
method_name
=
method
.
__name__
update_wrapper
(
self
,
self
.
method
)
def
__get__
(
self
,
instance
,
owner
)
:
print
"-+"
*
20
print
"__get__"
print
self
,
instance
,
owner
value
=
self
.
method
(
instance
)
setattr
(
instance
,
self
.
method_name
,
value
)
print
"-+"
*
20
return
value
class
T2
(
object
)
:
def
__init__
(
self
)
:
self
.
_t
=
1
@LazyLoad
def
resource
(
self
)
:
print
"execute it in resource !"
z
=
[
str
(
i
)
for
i
in
range
(
0
,
10
)
]
return
","
.
join
(
z
)
t2
=
T2
(
)
print
type
(
t2
.
resource
)
print
t2
.
resource
print
t2
.
resource
使用装饰器和非数据描述自定义实现
staticmethod
class
StaticObj
(
object
)
:
"""这里是自定义的非数据描述符"""
def
__init__
(
self
,
method
)
:
self
.
method
=
method
def
__get__
(
self
,
instance
,
owner
)
:
return
self
.
method
def
static_m
(
func
)
:
return
StaticObj
(
func
)
class
T3
(
object
)
:
def
__init__
(
self
)
:
print
"create it "
@static_m
def
test
(
a
,
b
)
:
print
1
,
a
,
b
print
T3
.
test
(
2
,
3
)
# 输出 1 2 3
可以像下面一样理解
-
test
经过装饰器后,就是StaticObj(test)
-
然后点操作会执行
__get__
返回 test 函数,此函数是不需要绑定的 -
后面的
(2,3)
会执行 test(2,3)
看不懂没关系,欢迎评论区讨论呦~~