在嵌套类中,如何访问外部类';从Python中的嵌套类中删除元素?
我有这样一个场景,我需要要求嵌套类将项附加到外部类中的列表中。这是一个伪代码,和我想做的很相似。我怎样才能让它工作呢在嵌套类中,如何访问外部类';从Python中的嵌套类中删除元素?,python,class,nested,Python,Class,Nested,我有这样一个场景,我需要要求嵌套类将项附加到外部类中的列表中。这是一个伪代码,和我想做的很相似。我怎样才能让它工作呢 class Outer(object): outerlist = [] class Inner(object): def __call__(self, arg1): outerlist.append(arg1) if __name__ == "__main__": f = Outer() f.Inner("apple") f.Inner(
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()
这就是我希望看到的-apple,orange
详细信息:OS X、Python 2.7您只能使用全局全名访问外部类:
class Outer(object):
outerlist = []
class Inner(object):
def __call__(self, arg1):
Outer.outerlist.append(arg1)
在python中,在任何情况下通常都不需要嵌套类。在某些用例中,在函数中定义类(使用作用域变量)是有意义的,但很少需要嵌套类。这将产生预期的结果 请注意
\uuuu new\uuuu
(第A行)的用法。这意味着,不是正确地进行任何构造,而是在列表的后面添加内容。此外,要访问包含类的类属性,只需使用外部类的名称(B行)
最后参见第C行。列表不是一个函数。在原始代码中有一些额外的括号
class Outer(object):
outerlist = []
class Inner(object):
def __new__(self, arg1): #A
Outer.outerlist.append(arg1) #B
f = Outer()
f.Inner("apple")
f.Inner("orange")
print f.outerlist #C
既然我了解了你的设计,你就大错特错了 首先,外部是一个类;它不会被调用。您的第17行只会构造一个空的
外部对象,而不使用它。如果要“调用”外部对象,可以定义一个\uuuuu init\uuuu
方法,或者,正如Sheena所建议的,定义一个\uuu new\uuuuu
并拦截初始化,因为实际上并不需要初始化的对象
老实说,我不认为一个不了解\uuuu call\uuuu
如何工作的人应该尝试构建类似这样的复杂东西。但如果你坚持,请继续读下去
在类中而不是在实例中收集此类内容是一种非常奇怪的设计,可能很糟糕。请记住,类变量实际上是全局变量,包含所有这些变量。如果您尝试以可重入方式使用Outer
,或者从多个线程/事件处理程序/greenlets/任何东西中使用,那么这些用法最终都会互相践踏。即使你认为现在这不可能成为一个问题,但在将来的某个时候它可能会成为一个问题
您可以创建一个Outer
实例,并将其成员用作装饰器。例如:
from outer_library import Outer
outer = Outer()
@outer.get("/")
…
但我不确定这是否更好。这里的整个设计似乎涉及到在模块级别执行操作,尽管看起来您只是在定义普通函数并在最后调用函数。事实上,你已经设法使自己困惑,这应该是一个多么令人困惑的设计证据
但是如果您确实想这样做,您可能想做的是在Outer.\uuuu init\uuu
方法中定义类,并将它们分配给实例成员。类是一级值,可以像其他值一样分配给变量。然后,使用这些类的\uuuuu init\uuuuu
(或\uuuu new\uuuuuu
)方法来完成所需的工作,使这些类模拟函数
这似乎令人困惑或误导。但是请记住,您试图做的全部工作是以一种看起来像方法的方式使用一个类,因此这种混淆是问题固有的。但是如果您愿意,您可以将decorator编写为函数(在本例中,作为Outer
的普通实例方法);这只会让问题的另一部分变得更难,而不是这一部分
设计这样的东西的一种更普通的方法是将Outer
制作成一个完全正常的类,人们可以对其进行子类化或创建实例,并提供一种显式的非奇特的方式将处理程序方法或函数附加到URL。然后,一旦这起作用,设计一种方法来简化与装饰器的处理程序注册。为什么不将外部类实例作为参数传递给内部类方法?您可以通过这种方式访问外部类实例的成员
class Outer(object):
outerlist = []
class Inner(object):
def __init__(self, outer_self):
self.outer = outer_self
def __call__(self, arg1):
self.outer.outerlist.append(arg1)
if __name__ == "__main__":
f = Outer()
i = f.Inner(f)
i("apple")
i("orange")
print f.outerlist
我认为picmate指出的选项(将外部类作为内部类的输入传递)对于这个特定问题是一个很好的选择。请注意,它也可以在不必“嵌套”类的情况下工作(在我看来,这里要避免一些事情,因为它是不必要的)。注意,我还将内部类的初始化嵌入到外部类中(这一步不是严格需要的,但我在这里包括它是为了说明):
为什么要使用嵌套类呢?所以我尝试让外部类包含接受参数的装饰器,最好的方法是将装饰器编写为类是的,使用类作为装饰器是个好主意,但这并不意味着需要使用嵌套类。你想解决什么问题?@sri:是的,我同意,装饰师应该是一个职业。但是你装饰的类应该是一个完全独立的类。没有嵌套。一些次要问题:我假设您想要打印f.outerlist,而不是f.outerlist()
,因为您无法调用列表。此外,虽然您可以通过实例访问类变量,但通过类访问它们通常不会太混乱,如print Outer.outerlist
。(事实上,您通过f
访问它意味着我必须问:\uuuuuu new\uuuuu
每次调用\uuu init\uuuuu
或\uu调用
时都会调用它吗?)?这很好。@sri:不是每次它都执行一个\uuuuu调用\uuuuu
——这是一个实例方法,可以多次调用。当类通常需要创建实例时,在\uuuu init\uuu
@Sheena之前调用一次:它们是“类变量”。“static”一词指的是既不与类也不与实例相关联的事物,“properties”是一种特殊的类变量,其描述符使它们的行为类似于实例变量。但除此之外,一切都在钱上。这主要是r
class Outer(object):
outerlist = []
def __init__(self):
self.Inner=Inner(Outer=self)
def get_basket(self):
print "Outer basket: %s" %(self.outerlist)
class Inner(object):
def __init__(self,Outer):
self.Outer=Outer
def __call__(self, arg1):
self.Outer.outerlist.append(arg1)
def get_basket(self):
print "Inner basket: %s" %(self.Outer.outerlist)
if __name__ == "__main__":
f = Outer()
print "Initial state"
f.get_basket()
f.Inner.get_basket()
f.Inner("apple")
f.Inner("orange")
print "Final state"
f.get_basket()
f.Inner.get_basket()