我正在为Python库设计API,并且遇到了一种情况,我认为我的想象力可能已经超过了Python的相当大的能力。
(我想向任何可能被我的设计的Ruby-ness冒犯的Pythonistas道歉)
基本上,有一个包含几个方法的类,每个方法都返回self,因此可以将它们链接在一起。所以:
>>> a = MyKlass()
>>> b = a.method_one()
>>> c = b.method_two()都是一样的
>>> a = MyKlass()
>>> c = a.method_one().method_two()我的问题是,是否有可能使括号成为可选的。我已经学习了一些关于使用__getattr__和__call__来操作可调用对象的知识,但还没有完全实现这一点。现在,我让类的__getattr__检查属性,然后确定name是方法还是属性(或者更准确地说,它是否是可调用的)。
我的问题是,如果它是一个可调用的,我需要__getattr__来做这样的事情:
>>> class MyKlass(object):
>>> def __getattr__(self, name):
>>> # pseudocode, you get the idea...
>>> if name is callable:
>>> def callme(*args, **kwds):
>>> # do stuff
>>> return callme
>>> else:
>>> # just return the attribute所以它返回一个可调用的对象。这意味着我不能把括号设为可选的,因为callable对象会被返回,但永远不会被调用:
>>> a = MyKlass()
>>> c = a.method_one.method_two # AttributeError, since a bound function object does not have attribute "method_two"我想要做到这一点的唯一方法是能够在代码中“向前看”,并确定name后面是否有括号。然后,如果name是可调用但不可调用的,我可以返回不带参数调用name的结果,而不是返回一个可调用的对象。
我在想,这可能是不可行的,但我想无论如何我都会请教上师。
发布于 2011-07-06 03:41:58
我认为你想这么做是疯了。你有什么理由?带参数的方法呢?(请参见下面的示例。)
如果您使用__getattribute__而不是__getattr__,那么它似乎适用于没有参数的方法。
工作示例:
class Test(object):
def __getattribute__(self, name):
attr = super(Test, self).__getattribute__(name)
if callable(attr):
return attr()
return attr
def f(self):
print 'f'
return self
def g(self):
print 'g'
return self
def h(self, x):
print x
return self
t = Test()
t.f.g # Works fine
t.f().g # Fails - the parens aren't optional, they must be left off now
t.f.g.h(1) # Fails - unable to provide an argument要绕过参数问题,您可以检查函数,并仅在它不接受任何参数(除self之外)时才调用它。请参阅:http://docs.python.org/library/inspect.html
帮你自己一个忙,别再走这条路了。
发布于 2011-07-06 03:46:19
没有括号,你就有了对函数的引用,有了它们,你就有了调用的结果。这是Python语法的基本部分(这种一致性是一件好事!)。
您总是可以使用Python的property函数(或相关的装饰器)使方法在幕后作为属性的别名工作,这将实现您想要的效果。然而,这表明你正在编写副作用很大的代码,这是一个糟糕的想法。
这样的链接在jQuery中很流行,因为jQuery的唯一目的就是在DOM中产生副作用。通常,这在其他地方是不明智的,因为它使您的应用程序非常难以调试和测试。
https://stackoverflow.com/questions/6587858
复制相似问题