- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章python实现装饰器、描述符由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
概要 。
本人python理论知识远达不到传授级别,写文章主要目的是自我总结,并不能照顾所有人,请见谅,文章结尾贴有相关链接可以作为补充 。
全文分为三个部分装饰器理论知识、装饰器应用、装饰器延申 。
装饰器基础 。
无参装饰器 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
'''
假定有一个需求是:打印程序函数运行顺序
此案例打印的结果为:
foo1 function is starting
foo2 function is starting
'''
from
functools
import
wraps
def
NoParamDec(func):
#函数在被装饰器装时后,其函数属性也会改变,wraps作用就是保证被装饰函数属性不变
@wraps
(func)
def
warpper(
*
args,
*
*
kwargs):
print
(
'{} function is starting'
.
format
(func.__name__))
return
func(
*
args,
*
*
kwargs)
return
warpper
#python黑魔法省略了NoParamDec=NoParamDec(foo1)
@NoParamDec
def
foo1():
foo2()
@NoParamDec
def
foo2():
pass
if
__name__
=
=
"__main__"
:
foo1()
|
有参装饰器 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
'''
假定有一个需求是:检查函数参数的类型,只允许匹配正确的函数通过程序
此案例打印结果为:
('a', 'b', 'c')
-----------------------分割线------------------------
ERROS!!!!b must be <class 'str'>
ERROS!!!!c must be <class 'str'>
('a', 2, ['b', 'd'])
'''
from
functools
import
wraps
from
inspect
import
signature
def
typeAssert(
*
args,
*
*
kwargs):
deco_args
=
args
deco_kwargs
=
kwargs
def
factor(func):
#python标准模块类,可以用来检查函数参数类型,只允许特定类型通过
sig
=
signature(func)
#将函数形式参数和规定类型进行绑定
check_bind_args
=
sig.bind_partial(
*
deco_args,
*
*
deco_kwargs).arguments
@wraps
(func)
def
wrapper(
*
args,
*
*
kwargs):
#将实际参数值和形式参数进行绑定
wrapper_bind_args
=
sig.bind(
*
args,
*
*
kwargs).arguments.items()
for
name, obj
in
wrapper_bind_args:
#遍历判断是否实际参数值是规定参数的实例
if
not
isinstance
(obj, check_bind_args[name]):
try
:
raise
TypeError(
'ERROS!!!!{arg} must be {obj} '
.
format
(
*
*
{
'arg'
: name,
'obj'
: check_bind_args[name]}))
except
Exception as e:
print
(e)
return
func(
*
args,
*
*
kwargs)
return
wrapper
return
factor
@typeAssert
(
str
,
str
,
str
)
def
inspect_type(a, b, c):
return
(a, b, c)
if
__name__
=
=
"__main__"
:
print
(inspect_type(
'a'
,
'b'
,
'c'
))
print
(
'{:-^50}'
.
format
(
'分割线'
))
print
(inspect_type(
'a'
,
2
, [
'b'
,
'd'
]))
|
装饰器链 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
'''
假定有一个需求是:
输入类似代码:
@makebold
@makeitalic
def say():
return "Hello"
输出:
<b><i>Hello</i></b>
'''
from
functools
import
wraps
def
html_deco(tag):
def
decorator(fn):
@wraps
(fn)
def
wrapped(
*
args,
*
*
kwargs):
return
'<{tag}>{fn_result}<{tag}>'
.
format
(
*
*
{
'tag'
: tag,
'fn_result'
: fn(
*
args,
*
*
kwargs)})
return
wrapped
return
decorator
@html_deco
(
'b'
)
@html_deco
(
'i'
)
def
greet(whom
=
''):
# 等价于 geet=html_deco('b')(html_deco('i)(geet))
return
'Hello'
+
(
' '
+
whom)
if
whom
else
''
if
__name__
=
=
"__main__"
:
print
(greet(
'world'
))
# -> <b><i>Hello world</i></b>
|
装饰器进阶 。
property 原理 。
通常,描述符是具有“绑定行为”的对象属性,其属性访问已经被描述符协议中的方法覆盖。这些方法是__get__()、__set__()和__delete__()。如果一个对象定义这些方法中的任何一个,它被称为一个描述符。如果对象定义__get__()和__set__(),则它被认为是数据描述符。仅定义__get__()的描述器称为非数据描述符(它们通常用于方法,但是其他用途也是可能的).
属性查找优先级为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
class
Property
(
object
):
'''
内部property是用c实现的,这里用python模拟实现property功能
代码参考官方doc文档
'''
def
__init__(
self
, fget
=
None
, fset
=
None
, fdel
=
None
, doc
=
None
):
self
.fget
=
fget
self
.fset
=
fset
self
.fdel
=
fdel
self
.__doc__
=
doc
def
__get__(
self
, obj, objtype
=
None
):
if
obj
is
None
:
return
self
if
self
.fget
is
None
:
raise
(AttributeError,
"unreadable attribute"
)
print
(
'self={},obj={},objtype={}'
.
format
(
self
,obj,objtype))
return
self
.fget(obj)
def
__set__(
self
, obj, value):
if
self
.fset
is
None
:
raise
(AttributeError,
"can't set attribute"
)
self
.fset(obj, value)
def
__delete__(
self
, obj):
if
self
.fdel
is
None
:
raise
(AttributeError,
"can't delete attribute"
)
self
.fdel(obj)
def
getter(
self
, fget):
return
type
(
self
)(fget,
self
.fset,
self
.fdel,
self
.__doc__)
def
setter(
self
, fset):
return
type
(
self
)(
self
.fget, fset,
self
.fdel,
self
.__doc__)
def
deleter(
self
, fdel):
return
type
(
self
)(
self
.fget,
self
.fset, fdel,
self
.__doc__)
class
Student(
object
):
@Property
def
score(
self
):
return
self
._score
@score
.setter
def
score(
self
, val ):
if
not
isinstance
( val,
int
):
raise
ValueError(
'score must be an integer!'
)
if
val >
100
or
val <
0
:
raise
ValueError(
'score must between 0 ~ 100!'
)
self
._score
=
val
if
__name__
=
=
"__main__"
:
s
=
Student()
s.score
=
60
s.score
|
staticmethod 原理 。
@staticmethod means: when this method is called, we don't pass an instance of the class to it (as we normally do with methods). This means you can put a function inside a class but you can't access the instance of that class (this is useful when your method does not use the instance). 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
class
StaticMethod
(
object
):
"python代码实现staticmethod原理"
def
__init__(
self
, f):
self
.f
=
f
def
__get__(
self
, obj, objtype
=
None
):
return
self
.f
class
E(
object
):
#StaticMethod=StaticMethod(f)
@StaticMethod
def
f( x):
return
x
if
__name__
=
=
"__main__"
:
print
(E.f(
'staticMethod Test'
))
|
classmethod 。
@staticmethod means: when this method is called, we don't pass an instance of the class to it (as we normally do with methods). This means you can put a function inside a class but you can't access the instance of that class (this is useful when your method does not use the instance). 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
class
ClassMethod
(
object
):
"python代码实现classmethod原理"
def
__init__(
self
, f):
self
.f
=
f
def
__get__(
self
, obj, klass
=
None
):
if
klass
is
None
:
klass
=
type
(obj)
def
newfunc(
*
args):
return
self
.f(klass,
*
args)
return
newfunc
class
E(
object
):
#ClassMethod=ClassMethod(f)
@ClassMethod
def
f(
cls
,x):
return
x
if
__name__
=
=
"__main__"
:
print
(E().f(
'classMethod Test'
))
|
原文链接:https://segmentfault.com/a/1190000013425128 。
最后此篇关于python实现装饰器、描述符的文章就讲到这里了,如果你想了解更多关于python实现装饰器、描述符的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
背景: 我最近一直在使用 JPA,我为相当大的关系数据库项目生成持久层的轻松程度给我留下了深刻的印象。 我们公司使用大量非 SQL 数据库,特别是面向列的数据库。我对可能对这些数据库使用 JPA 有一
我已经在我的 maven pom 中添加了这些构建配置,因为我希望将 Apache Solr 依赖项与 Jar 捆绑在一起。否则我得到了 SolarServerException: ClassNotF
interface ITurtle { void Fight(); void EatPizza(); } interface ILeonardo : ITurtle {
我希望可用于 Java 的对象/关系映射 (ORM) 工具之一能够满足这些要求: 使用 JPA 或 native SQL 查询获取大量行并将其作为实体对象返回。 允许在行(实体)中进行迭代,并在对当前
好像没有,因为我有实现From for 的代码, 我可以转换 A到 B与 .into() , 但同样的事情不适用于 Vec .into()一个Vec . 要么我搞砸了阻止实现派生的事情,要么这不应该发
在 C# 中,如果 A 实现 IX 并且 B 继承自 A ,是否必然遵循 B 实现 IX?如果是,是因为 LSP 吗?之间有什么区别吗: 1. Interface IX; Class A : IX;
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在阅读标准haskell库的(^)的实现代码: (^) :: (Num a, Integral b) => a -> b -> a x0 ^ y0 | y0 a -> b ->a expo x0
我将把国际象棋游戏表示为 C++ 结构。我认为,最好的选择是树结构(因为在每个深度我们都有几个可能的移动)。 这是一个好的方法吗? struct TreeElement{ SomeMoveType
我正在为用户名数据库实现字符串匹配算法。我的方法采用现有的用户名数据库和用户想要的新用户名,然后检查用户名是否已被占用。如果采用该方法,则该方法应该返回带有数据库中未采用的数字的用户名。 例子: “贾
我正在尝试实现 Breadth-first search algorithm , 为了找到两个顶点之间的最短距离。我开发了一个 Queue 对象来保存和检索对象,并且我有一个二维数组来保存两个给定顶点
我目前正在 ika 中开发我的 Python 游戏,它使用 python 2.5 我决定为 AI 使用 A* 寻路。然而,我发现它对我的需要来说太慢了(3-4 个敌人可能会落后于游戏,但我想供应 4-
我正在寻找 Kademlia 的开源实现C/C++ 中的分布式哈希表。它必须是轻量级和跨平台的(win/linux/mac)。 它必须能够将信息发布到 DHT 并检索它。 最佳答案 OpenDHT是
我在一本书中读到这一行:-“当我们要求 C++ 实现运行程序时,它会通过调用此函数来实现。” 而且我想知道“C++ 实现”是什么意思或具体是什么。帮忙!? 最佳答案 “C++ 实现”是指编译器加上链接
我正在尝试使用分支定界的 C++ 实现这个背包问题。此网站上有一个 Java 版本:Implementing branch and bound for knapsack 我试图让我的 C++ 版本打印
在很多情况下,我需要在 C# 中访问合适的哈希算法,从重写 GetHashCode 到对数据执行快速比较/查找。 我发现 FNV 哈希是一种非常简单/好/快速的哈希算法。但是,我从未见过 C# 实现的
目录 LRU缓存替换策略 核心思想 不适用场景 算法基本实现 算法优化
1. 绪论 在前面文章中提到 空间直角坐标系相互转换 ,测绘坐标转换时,一般涉及到的情况是:两个直角坐标系的小角度转换。这个就是我们经常在测绘数据处理中,WGS-84坐标系、54北京坐标系
在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在 .Net 7 下进行一次简单的演示. PeriodicTimer .
二分查找 二分查找算法,说白了就是在有序的数组里面给予一个存在数组里面的值key,然后将其先和数组中间的比较,如果key大于中间值,进行下一次mid后面的比较,直到找到相等的,就可以得到它的位置。
我是一名优秀的程序员,十分优秀!