在python中从内部类访问外部类

我有这样的情况

class Outer(object): def some_method(self): # do something class Inner(object): def __init__(self): self.Outer.some_method() # <-- this is the line in question 

我如何从Inner类访问Outer类的方法?

编辑 – 感谢您的答复。 我得出结论,我需要重新评估我是如何devise这个实现的,并提出一个更强大的方法。

嵌套类的方法不能直接访问外部类的实例属性。

请注意,即使创build了内部类的实例,也不一定存在外部类的实例。

事实上,经常build议不要使用嵌套类,因为嵌套并不意味着内部类和外部类之间的任何特定关系。

你正试图从内部类实例访问Outer的类实例。 所以只需使用工厂方法来构buildInner实例并将Outer实例传递给它。

 class Outer(object): def createInner(self): return Outer.Inner(self) class Inner(object): def __init__(self, outer_instance): self.outer_instance = outer_instance self.outer_instance.somemethod() def inner_method(self): self.outer_instance.anothermethod() 

也许我很生气,但这似乎很容易 – 事情是让你的内部类在外部类的方法…

 def do_sthg( self ): ... def messAround( self ): outerClassSelf = self class mooble(): def do_sthg_different( self ): ... outerClassSelf.do_sthg() 

加上…“自我”只是习惯使用,所以你可以这样做:

 def do_sthg( self ): ... def messAround( outerClassSelf ): class mooble(): def do_sthg_different( self ): ... outerClassSelf.do_sthg() 

可能会有人反对,你不能从外部类之外创build这个内部类…但这不是事实:

 class Bumblebee(): def do_sthg( self ): print "sthg" def giveMeAnInnerClass( outerClassSelf ): class mooble(): def do_sthg_different( self ): print "something diff\n" outerClassSelf.do_sthg() return mooble 

那么,在几英里远的地方:

 blob = Bumblebee().giveMeAnInnerClass()() blob.do_sthg_different() 

甚至把船推出来,扩展这个内部类(注意要获得super()的工作,你必须将mooble的类签名改为“class mooble(object)”

 class InnerBumblebeeWithAddedBounce( Bumblebee().giveMeAnInnerClass() ): def bounce( self ): print "bounce" def do_sthg_different( self ): super( InnerBumblebeeWithAddedBounce, self ).do_sthg_different() print "and more different" ibwab = InnerBumblebeeWithAddedBounce() ibwab.bounce() ibwab.do_sthg_different() 

你的意思是使用inheritance,而不是像这样嵌套类? 你在做什么并不能在Python中形成一堆意义。

你可以通过在内部类的方法中引用Outer.some_method来访问Outer的some_method,但是它不会像你期望的那样工作。 例如,如果你尝试这样做:

 class Outer(object): def some_method(self): # do something class Inner(object): def __init__(self): Outer.some_method() 

…当初始化一个Inner对象时,你会得到一个TypeError,因为Outer.some_method期望接收一个Outer实例作为它的第一个参数。 (在上面的例子中,你基本上是some_method作为Outer的类方法。

基于这个好主意,我的答案是针对同一个问题的答案(在https://stackoverflow.com/a/7152649/3787376 )解释说,因为我想创build自己的高质量解决scheme来解决这个问题,用Python的答案应该很容易理解。

 class higher_level__unknown_irrelevant_name__class: def __init__(self, ...args...): ...other code... # Important lines to access sub-classes. subclasses = self._subclass_container() self.some_subclass = subclasses["some_subclass"] del subclasses # Free up variable for other use. def sub_function(self, ...args...): ...other code... def _subclass_container(self): _parent_class = self # Create access to parent class. class some_subclass: def __init__(self): self._parent_class = _parent_class # Easy access from self. # Optional line, clears variable space, but SHOULD NOT BE USED # IF THERE ARE MULTIPLE SUBCLASSES as would stop their parent access. # del _parent_class class subclass_2: def __init__(self): self._parent_class = _parent_class # Return reference(s) to the subclass(es). return {"some_subclass": some_subclass, "subclass_2": subclass_2} 

主要代码“生产准备”(没有评论等)。 请记住用尖括号(例如<x> )中的每个值replace所需的值。

 class <higher_level_class>: def __init__(self): subclasses = self._subclass_container() self.<sub_class> = subclasses[<sub_class, type string>] del subclasses def _subclass_container(self): _parent_class = self class <sub_class>: def __init__(self): self._parent_class = _parent_class return {<sub_class, type string>: <sub_class>} 

该方法如何工作的说明(基本步骤):

  1. 创build一个名为_subclass_container的函数,作为一个包装来访问variablesself ,这是对更高级别的类(从函数内运行的代码)的引用。

    1. 创build一个名为_parent_class的variables,该variables是对此函数的selfvariables的引用, _subclass_container的子类可以访问(避免与子类中的其他selfvariables的名称冲突)。

    2. 将子类/子类作为字典/列表返回,以便调用_subclass_container函数的代码可以访问里面的子类。

  2. 在高级类(或其他需要的地方)中的__init__函数中,从函数_subclass_container接收返回的子类到variablessubclasses

  3. 将存储在subclassesvariables中的subclasses分配给更高级别的属性。

一些提示方便的方法:

使代码更容易地将子类分配给更高级别的类,并将其用于从具有 __init__ 函数 的更高级别类派生的类中

在主要代码的第12行之前插入:

  def _subclass_init(self): 

然后插入到主函数5-6的函数行中,用下面的代码代替行4-7:

  self._subclass_init(self) 

当有许多/未知数量的子类时,可以将子类分配给更高级的类。

用下面的代码replace第6行:

  for subclass_name in list(subclasses.keys()): setattr(self, subclass_name, subclasses[subclass_name]) 

这个解决scheme将会有用的示例场景,以及更高级别的类名不可能得到的地方:

创build一个名为“a”( class a: :)的类。 它有子类需要访问它(父)。 一个子类被称为“x1”。 在这个子类中,运行代码a.run_func()

然后创build另一个名为“b”的类,从类“a”( class b(a): :)派生 。 之后,一些代码运行b.x1() (调用b的子函数“x1”,派生子类)。 这个函数运行a.run_func() ,调用类“a”的函数“run_func”, 而不是它的父类“b”的函数“run_func”(因为它应该),因为类“a “被设置为指代类”a“的function,因为那是它的父母。

这会导致问题(例如,如果函数a.run_func已被删除),唯一的解决scheme,而不重写a.x1类中的代码将重新定义子类x1更新的代码从所有类派生的类“a”显然是困难的,不值得。

我发现这一点 。

调整以适应您的问题,这是答案:

 class Outer(object): def some_method(self): # do something class _Inner(object): def __init__(self, outer): outer.some_method() def Inner(self): return Inner(self) 

我相信你可以以某种方式写一个装饰这个或什么的:)
/编辑: 有点

另一种可能性

 class _Outer (object): # Define your static methods here, eg @staticmethod def subclassRef (): return Outer class Outer (_Outer): class Inner (object): def outer (self): return _Outer def doSomething (self): outer = self.outer () # Call your static mehthods. cls = outer.subclassRef () return cls () 

扩展@ tsnorri的有力思想,外在的方法可能是一个静态的方法 :

 class Outer(object): @staticmethod def some_static_method(self): # do something class Inner(object): def __init__(self): self.some_static_method() # <-- this will work later Inner.some_static_method = some_static_method 

现在这条线应该在实际调用的时候工作。

上面的代码中的最后一行给出了Inner类的一个静态方法,它是Outer静态方法的一个克隆。


这利用了两个Pythonfunction, function是对象 , 范围是文本 。

通常,本地作用域引用(文本)当前函数的本地名称。

在我们的情况下…或当前课程 。 因此,对Outer类( Innersome_static_method )定义的“local”对象可以在该定义中直接引用。

您可以使用元类轻松访问外部类:在创build外部类之后,请检查它是否为任何类的属性字典(或者应用您需要的任何逻辑 – 我的例子只是简单的例子)并设置相应的值:

 import six import inspect # helper method from `peewee` project to add metaclass _METACLASS_ = '_metaclass_helper_' def with_metaclass(meta, base=object): return meta(_METACLASS_, (base,), {}) class OuterMeta(type): def __new__(mcs, name, parents, dct): cls = super(OuterMeta, mcs).__new__(mcs, name, parents, dct) for klass in dct.values(): if inspect.isclass(klass): print("Setting outer of '%s' to '%s'" % (klass, cls)) klass.outer = cls return cls # @six.add_metaclass(OuterMeta) -- this is alternative to `with_metaclass` class Outer(with_metaclass(OuterMeta)): def foo(self): return "I'm outer class!" class Inner(object): outer = None # <-- by default it's None def bar(self): return "I'm inner class" print(Outer.Inner.outer) >>> <class '__main__.Outer'> assert isinstance(Outer.Inner.outer(), Outer) print(Outer().foo()) >>> I'm outer class! print(Outer.Inner.outer().foo()) >>> I'm outer class! print(Outer.Inner().outer().foo()) >>> I'm outer class! print(Outer.Inner().bar()) >>> I'm inner class! 

使用这种方法,您可以轻松地绑定和引用彼此之间的两个类。