Skip to content

Commit a25c4c0

Browse files
committed
8.20小节完成
1 parent 7582d52 commit a25c4c0

File tree

3 files changed

+108
-4
lines changed

3 files changed

+108
-4
lines changed

basic/mystring/strformat.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
__author__ = 'Xiong Neng'
99

10+
1011
def simple():
1112
# 一般的%形式的格式化
1213
a = 42
@@ -33,7 +34,8 @@ def simple():
3334
name = 'Elwood'
3435
age = 99
3536
print('%(name)s is %(age)s years old.' % vars())
36-
#print('{0} {1} {2}'.format())
37+
# print('{0} {1} {2}'.format())
38+
3739

3840
def senior():
3941
"""高级字符串格式化"""

cookbook/c08/p20_invoke_bystr.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env python
2+
# -*- encoding: utf-8 -*-
3+
"""
4+
Topic: 通过字符串调用方法
5+
Desc :
6+
"""
7+
8+
import math
9+
10+
11+
class Point:
12+
def __init__(self, x, y):
13+
self.x = x
14+
self.y = y
15+
16+
def __repr__(self):
17+
# !r表示调用后面参数的__repr__()方法
18+
return 'Point({!r:},{!r:})'.format(self.x, self.y)
19+
20+
def distance(self, x, y):
21+
return math.hypot(self.x - x, self.y - y)
22+
23+
24+
p = Point(2, 3)
25+
d = getattr(p, 'distance')(0, 0) # Calls p.distance(0, 0)
26+
27+
import operator
28+
29+
operator.methodcaller('distance', 0, 0)(p)
30+
31+
points = [
32+
Point(1, 2),
33+
Point(3, 0),
34+
Point(10, -3),
35+
Point(-5, -7),
36+
Point(-1, 8),
37+
Point(3, 2)
38+
]
39+
# Sort by distance from origin (0, 0)
40+
points.sort(key=operator.methodcaller('distance', 0, 0))

source/c08/p20_call_method_on_object_by_string_name.rst

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,76 @@
55
----------
66
问题
77
----------
8-
todo...
8+
你有一个字符串形式的方法名称,想通过它调用某个对象的对应方法。
9+
10+
|
911
1012
----------
1113
解决方案
1214
----------
13-
todo...
15+
最简单的情况,可以使用 ``getattr()`` :
16+
17+
.. code-block:: python
18+
19+
import math
20+
21+
class Point:
22+
def __init__(self, x, y):
23+
self.x = x
24+
self.y = y
25+
26+
def __repr__(self):
27+
return 'Point({!r:},{!r:})'.format(self.x, self.y)
28+
29+
def distance(self, x, y):
30+
return math.hypot(self.x - x, self.y - y)
31+
32+
33+
p = Point(2, 3)
34+
d = getattr(p, 'distance')(0, 0) # Calls p.distance(0, 0)
35+
36+
另外一种方法是使用 ``operator.methodcaller()`` ,例如:
37+
38+
.. code-block:: python
39+
40+
import operator
41+
operator.methodcaller('distance', 0, 0)(p)
42+
43+
当你需要通过相同的参数多次调用某个方法时,使用 ``operator.methodcaller`` 就很方便了。
44+
比如你需要排序一系列的点,就可以这样做:
45+
46+
.. code-block:: python
47+
48+
points = [
49+
Point(1, 2),
50+
Point(3, 0),
51+
Point(10, -3),
52+
Point(-5, -7),
53+
Point(-1, 8),
54+
Point(3, 2)
55+
]
56+
# Sort by distance from origin (0, 0)
57+
points.sort(key=operator.methodcaller('distance', 0, 0))
58+
59+
|
1460
1561
----------
1662
讨论
1763
----------
18-
todo...
64+
调用一个方法实际上是两部独立操作,第一步是查找属性,第二步是函数调用。
65+
因此,为了调用某个方法,你可以首先通过 ``getattr()`` 来查找到这个属性,然后再去以函数方式调用它即可。
66+
67+
``operator.methodcaller()`` 创建一个可调用对象,并同时提供所有必要参数,
68+
然后调用的时候只需要将实例对象传递给它即可,比如:
69+
70+
.. code-block:: python
71+
72+
>>> p = Point(3, 4)
73+
>>> d = operator.methodcaller('distance', 0, 0)
74+
>>> d(p)
75+
5.0
76+
>>>
77+
78+
通过方法名称字符串来调用方法通常出现在需要模拟 ``case`` 语句或实现访问者模式的时候。
79+
参考下一小节获取更多高级例子。
80+

0 commit comments

Comments
 (0)