我尝试使用元类来使用自定义特殊方法生成类 - 特别是__call__
。类的生成取决于调用构造函数的参数。我遇到了一个奇怪的效果,简化示例如下:
def trick(self, *args, **kwargs):
print "Works!"
class Test1Factory(type):
def __new__(mcls, name, bases, namespace):
namespace['__call__'] = trick
return type.__new__(mcls, name, bases, namespace)
class Test1(object):
__metaclass__ = Test1Factory
def __init__(self, value):
self._value = value
t1 = Test1(1)
t1() # "Works!"
它有效,但它并不真正有用,因为__new__
中无法访问构造函数参数。 type.__call__
应该做到这一点:
import types
class Test2Factory(type):
def __call__(self, *args, **kwargs):
obj = type.__call__(self, *args, **kwargs)
setattr(obj, '__call__', types.MethodType(trick, obj, Test2))
return obj
class Test2(object):
__metaclass__ = Test2Factory
def __init__(self, value):
self._value = value
t2 = Test2(2)
t2.__call__() # "Works!"
t2() # TypeError: 'Test2' object is not callable
据我了解,instance()
与instance.__call__()
类似,但在此情况并非如此。使用类的__new__
静态方法也是如此。我有一个根本不使用元类的解决方法,但只想了解这些现象。 Python版本是2.7.5
答案 0 :(得分:0)
错误的假设可能在“instance()
与instance.__call__()
类似”,因为在__call__
中没有查找instance
,而是在实例的类型中。也就是说,使用的__call__
不是instance
的{{1}},而是instance.__class__
或type(instance)
的。{/ p>
__call__
上定义的任何instance
属性都可以作为任何其他属性定期访问,但在instance
调用instance()
时不会使用。这是Python语义的一部分。
尝试在实例及其类型上定义__call__
,看看你得到了什么。
如果我正确地理解了这个问题,那么这个问题与我的另一个问题具有相同的背景,并且得到了答案(在问题的帖子中通过实验进行了演示):“How do Python tell “this is called as a function”?”。