我有这种情况,我需要让嵌套类将项追加到外部类的列表中. Heres伪代码类似于我想要做的事情.我怎么去上班呢?
class Outer(object):
outerlist = []
class Inner(object):
def __call__(self, arg1):
outerlist.append(arg1)
if __name__ == "__main__":
f = Outer()
f.Inner("apple")
f.Inner("orange")
print f.outerlist()
这是我希望看到的 – 苹果,橙色
细节:
OS X,Python 2.7
解决方法:
既然我理解了你的设计,你就会把事情弄错.
首先,外面是一个阶级;它没有__call__ed.你的第17行只是构造一个空的Outer对象而不做任何事情.如果你想“调用”外部对象,你可以定义一个__init__方法 – 或者像Sheena建议的那样定义一个__new__并拦截初始化,因为你实际上并不需要初始化对象.
老实说,我不认为有人不理解__call__如何工作应该试图建立一些像这样棘手的东西.但如果你坚持,请继续阅读.
在类中而不是实例中收集这种东西是一种非常奇怪的,可能是坏的设计.请记住,类变量实际上是全局变量,所有这些都需要.如果您尝试重新使用外部,或者尝试使用多个线程/事件处理程序/ greenlets /其他任何东西,那么这些用途最终将会彼此重叠.即使你认为现在不太可能成为一个问题,它可能会在未来的某个时候出现.
您可以创建一个外部实例,并将其成员用作装饰器.例如:
from outer_library import Outer
outer = Outer()
@outer.get("/")
…
但我不确定那会好得多.这里的整个设计似乎涉及在模块级执行操作,即使看起来你只是定义了正常的函数并在最后调用了一个函数.你设法让自己迷惑的事实应该证明这是一个令人困惑的设计.
但是如果你想这样做,你可能想要做的是在Outer .__ init__方法中定义类,并将它们分配给实例成员.类是一等值,可以像任何其他值一样分配给变量.然后,使用这些类的__init __(或__new__)方法来完成您想要的工作,使类模拟函数.
这可能看起来令人困惑或误导.但要记住,你要做的事情的重点在于以一种看起来像方法的方式使用一个类,因此这种混淆是问题所固有的.但如果您愿意,可以将装饰器编写为函数(在本例中,作为Outer的常规实例方法);它只是使问题的另一部分变得更难而不是这部分.
设计类似这样的东西的更常规的方法是使Outer成为一个完全正常的类,人们可以子类或创建实例,并提供一种明确的非奇特方式将处理程序方法或函数附加到URL.然后,一旦它工作,设计一种方法来简化与装饰器的处理程序注册.