2

是否可以为方法编写包装函数?

>>> lowtide = [ 'oh', 'i', 'do', 'like', 'to', 'be', 'beside', 'the', 'seaside' ]

>>> [ x.capitalize() for x in lowtide ]
['Oh', 'I', 'Do', 'Like', 'To', 'Be', 'Beside', 'The', 'Seaside']

>>> list(map(lambda x: x.capitalize(), lowtide))
['Oh', 'I', 'Do', 'Like', 'To', 'Be', 'Beside', 'The', 'Seaside']


>>> def mef(m):
...     def _mef(m,x):
...         return x.m()
...     return partial(_mef, m)
... 
>>> list(map(mef(capitalize), lowtide))

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'capitalize' is not defined
4

3 回答 3

8

你可以简单地做

list(map(str.capitalize, lowtide))

在 Python 3.x 中,str.capitalize()是一个采用单个参数的函数self

在 Python 2.x 中,str.capitalize()是一种“未绑定方法”,但其行为类似于采用单个参数的函数。

于 2012-07-19T22:47:40.157 回答
5

虽然您可以使用str.capitalizeand unicode.capitalize,但如果您假设某种类型,这些可能会失败......最安全的方法是只使用:

from operator import methodcaller
capitalize = methodcaller('capitalize')

这保证了对对象使用正确的方法,并且还允许成功完成鸭子类型。

摘自我在 Google Groups/comp.lang.python 2010 年 8 月 23 日发布的帖子

使用 methodcaller 允许您“保留” Python 的鸭子类型以及子类中的任何覆盖方法。在您的示例中,这可能是矫枉过正,因为您只处理一个类

另一个(复杂的)示例:

class mystr(str):
    def lower(self):
        return self.upper()

>>> s = mystr('abc')
>>> s.lower()
'ABC'

>>> lower = methodcaller('lower')
>>> lower(s)
'ABC'

>>> str.lower(s)
'abc'

^^^ 很可能不正确

它还增加了一点灵活性(诚然,可以使用 functools.partial 进行模拟):

split_tab = methodcaller('split', '\t')
split_comma = methodcaller('split', ',')
于 2012-07-19T22:56:09.250 回答
1

这是您如何重写mef函数以使其正常工作的方法。这里使用的好处str.capitalize是它也适用于 Unicode 字符串以及 Python 2.x:

def mef(m):
    def _mef(x):
        return getattr(x, m)()
    return _mef

list(map(mef('capitalize'), lowtide))

请注意,这与使用lambda x: x.capitalize().

于 2012-07-19T22:51:06.537 回答