8.20小节完成
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
__author__ = 'Xiong Neng'
|
||||
|
||||
|
||||
def simple():
|
||||
# 一般的%形式的格式化
|
||||
a = 42
|
||||
@@ -33,7 +34,8 @@ def simple():
|
||||
name = 'Elwood'
|
||||
age = 99
|
||||
print('%(name)s is %(age)s years old.' % vars())
|
||||
#print('{0} {1} {2}'.format())
|
||||
# print('{0} {1} {2}'.format())
|
||||
|
||||
|
||||
def senior():
|
||||
"""高级字符串格式化"""
|
||||
|
||||
40
cookbook/c08/p20_invoke_bystr.py
Normal file
40
cookbook/c08/p20_invoke_bystr.py
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
"""
|
||||
Topic: 通过字符串调用方法
|
||||
Desc :
|
||||
"""
|
||||
|
||||
import math
|
||||
|
||||
|
||||
class Point:
|
||||
def __init__(self, x, y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
def __repr__(self):
|
||||
# !r表示调用后面参数的__repr__()方法
|
||||
return 'Point({!r:},{!r:})'.format(self.x, self.y)
|
||||
|
||||
def distance(self, x, y):
|
||||
return math.hypot(self.x - x, self.y - y)
|
||||
|
||||
|
||||
p = Point(2, 3)
|
||||
d = getattr(p, 'distance')(0, 0) # Calls p.distance(0, 0)
|
||||
|
||||
import operator
|
||||
|
||||
operator.methodcaller('distance', 0, 0)(p)
|
||||
|
||||
points = [
|
||||
Point(1, 2),
|
||||
Point(3, 0),
|
||||
Point(10, -3),
|
||||
Point(-5, -7),
|
||||
Point(-1, 8),
|
||||
Point(3, 2)
|
||||
]
|
||||
# Sort by distance from origin (0, 0)
|
||||
points.sort(key=operator.methodcaller('distance', 0, 0))
|
||||
@@ -5,14 +5,76 @@
|
||||
----------
|
||||
问题
|
||||
----------
|
||||
todo...
|
||||
你有一个字符串形式的方法名称,想通过它调用某个对象的对应方法。
|
||||
|
||||
|
|
||||
|
||||
----------
|
||||
解决方案
|
||||
----------
|
||||
todo...
|
||||
最简单的情况,可以使用 ``getattr()`` :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import math
|
||||
|
||||
class Point:
|
||||
def __init__(self, x, y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
def __repr__(self):
|
||||
return 'Point({!r:},{!r:})'.format(self.x, self.y)
|
||||
|
||||
def distance(self, x, y):
|
||||
return math.hypot(self.x - x, self.y - y)
|
||||
|
||||
|
||||
p = Point(2, 3)
|
||||
d = getattr(p, 'distance')(0, 0) # Calls p.distance(0, 0)
|
||||
|
||||
另外一种方法是使用 ``operator.methodcaller()`` ,例如:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import operator
|
||||
operator.methodcaller('distance', 0, 0)(p)
|
||||
|
||||
当你需要通过相同的参数多次调用某个方法时,使用 ``operator.methodcaller`` 就很方便了。
|
||||
比如你需要排序一系列的点,就可以这样做:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
points = [
|
||||
Point(1, 2),
|
||||
Point(3, 0),
|
||||
Point(10, -3),
|
||||
Point(-5, -7),
|
||||
Point(-1, 8),
|
||||
Point(3, 2)
|
||||
]
|
||||
# Sort by distance from origin (0, 0)
|
||||
points.sort(key=operator.methodcaller('distance', 0, 0))
|
||||
|
||||
|
|
||||
|
||||
----------
|
||||
讨论
|
||||
----------
|
||||
todo...
|
||||
调用一个方法实际上是两部独立操作,第一步是查找属性,第二步是函数调用。
|
||||
因此,为了调用某个方法,你可以首先通过 ``getattr()`` 来查找到这个属性,然后再去以函数方式调用它即可。
|
||||
|
||||
``operator.methodcaller()`` 创建一个可调用对象,并同时提供所有必要参数,
|
||||
然后调用的时候只需要将实例对象传递给它即可,比如:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> p = Point(3, 4)
|
||||
>>> d = operator.methodcaller('distance', 0, 0)
|
||||
>>> d(p)
|
||||
5.0
|
||||
>>>
|
||||
|
||||
通过方法名称字符串来调用方法通常出现在需要模拟 ``case`` 语句或实现访问者模式的时候。
|
||||
参考下一小节获取更多高级例子。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user