Skip to main content
 首页 » 编程设计

Python API之创建可选括号的模式

2025年05月04日17sharpest

我正在为 Python 库设计 API,并且遇到了一种情况,我认为我的想象力可能已经超过了 Python 的相当大的能力。

(我想向任何可能被我设计的 Ruby-ness 冒犯的 Pythonista 道歉)

基本上,有一个带有几个方法的类,每个方法都返回 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 

所以它返回一个可调用对象。不过,这意味着我无法将括号设为可选,因为可调用对象将被返回,但从未被调用:

>>> a = MyKlass() 
>>> c = a.method_one.method_two    # AttributeError, since a bound function object does not have attribute "method_two" 

我想到的唯一方法是能够在代码中“向前看”并确定 name 后面是否有括号。然后,如果 name 是可调用但未被调用的,我可以返回调用 name 而不带参数的结果,而不是返回可调用对象。

我在想这可能是不可行的,但我想无论如何我都会问问大师。

请您参考如下方法:

我认为您想要这样做是疯了。你有什么理由?带参数的方法呢? (参见下面的示例。)

如果您使用 __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

帮自己一个忙,不要再走这条路了。