【发布时间】:2014-07-27 12:55:25
【问题描述】:
Here in this IPython Notebook 我找到了一个关于生成器和函数式编程的演示文稿。我偶然发现了__metaclass__:
为什么
Real和float是Accounting的参数?现在一般在bases里面是什么,但是需要在里面写Real和float吗?__abstractmethods__有什么作用?我在通常的特殊方法列表中找不到它。作者是否通过使用这两个 for 循环来丰富他的
Accounting类与其他类的方法?为什么
Accounting(getattr(float,meth)(*args, **kwargs))不会导致无限循环?与第二个版本相比,这里发生了什么?
首先,这是与我的问题相关的摘录:
class Accounting(Real, float):
def __metaclass__(name, bases, body):
for method in Real.__abstractmethods__:
if method not in body:
body[method] = (lambda meth: lambda *args, **kwargs: Accounting(getattr(float,meth)(*args, **kwargs)))(method)
for method in ('__ne__','__nonzero__',):
if method not in body:
body[method] = (lambda meth: lambda *args, **kwargs: getattr(float,meth)(*args, **kwargs))(method)
return Real.__metaclass__(name, bases, body)
__new__ = float.__new__
这是整个代码:
from numbers import Real
class Accounting(Real, float):
def __metaclass__(name, bases, body):
for method in Real.__abstractmethods__:
if method not in body:
body[method] = (lambda meth: lambda *args, **kwargs: Accounting(getattr(float,meth)(*args, **kwargs)))(method)
for method in ('__ne__','__nonzero__',):
if method not in body:
body[method] = (lambda meth: lambda *args, **kwargs: getattr(float,meth)(*args, **kwargs))(method)
return Real.__metaclass__(name, bases, body)
__new__ = float.__new__
def __format__(self, fmt):
return { 1: ' %s'%float.__format__(self, fmt),
0: ' %s'%float.__format__(self, fmt).replace('0', '-'),
-1: '(%s)'%float.__format__(self, fmt) }[cmp(self,0)]
然后在这里使用代码:
template = '{region:<{align}} {profit:>14,.0f}'.format
def output(markets, write=print, template=template):
align = max(map(len,markets))
for region, profit in markets.items():
line = template(region=region, profit=profit, align=align)
write(line)
output({region:Accounting(profit) for region, profit in markets.items()})
输出:
Central America ( -675,140)
US ( -2,724,620)
Antarctica -
Asia ( -3,614,396)
UK ( -2,380,001)
EU 771,665
CEMEA 3,480,172
【问题讨论】:
-
如果你不懂元类,你就不需要元类:)
-
这里有一些关于
__abstractmethods__的信息。 -
这里使用元类看起来像是覆盖 format 方法的不必要的复杂方法 - 但也许这里还有其他东西。
标签: python class metaprogramming