Python v2 嵌套子类“未定义全局名称 '<ClassName>'”

DoS*_*DoS 2 python class python-2.x

首先,我要说的是,我已经对此进行了几天的广泛研究,但没有运气。我看过很多例子和类似的情况,例如这个,但到目前为止,没有什么能够解决我的问题。

我的问题是我有一个Python项目,它有一个主类,有两个嵌套类(是的,我知道),其中一个类是第一个类的子类。我不明白为什么我不断得到NameError: global name 'InnerSubClass' is not defined

我理解范围界定(有问题的两个类都在同一范围内),但我尝试的任何方法似乎都无法解决该问题(我想将两个类的嵌套保持在最低限度),尽管这个问题对其他人也适用。

这是我正在尝试做的一个简单示例:

class SomeClass(object):
        def __init__(self):

            """lots of other working stuff"""


class MainClass(object):
    def __init__(self):
        self.stuff = []
        self.moreStuffs = []

    class InnerClass(object):
        def __init__(self, thing, otherThing):
            self.thing = thing
            self.otherThing = otherThing
            self.otherStuff = []

    class InnerSubClass(InnerClass):
        def __init__(self, thing, otherThing, newThing):
            super(InnerSubClass).__init__(thing, otherThing)
            self.newThing = newThing

        """other code that worked before the addition of 'InnerSubClass'"""

    def doSomething(self):
        innerclass = self.InnerSubClass('thisthing', 'thatthing', 'thingthing')
        print("just more thing words %s" % innerclass.newThing)


myThing = MainClass()
myThing.doSomething()
Run Code Online (Sandbox Code Playgroud)

我尝试过改变super(InnerSubClass).__init__(thing, otherThing)super(InnerClass.InnerSubClass).__init__(thing, otherThing)super(MainClass.InnerClass.InnerSubClass).__init__(thing, otherThing)没有成功。我让“InnerSubClass”直接从对象InnerSubClass(object):等继承,但它仍然不起作用。

当然,我距离经验丰富的 python 开发人员还很远,并且主要来自其他编译的面向对象语言,并且似乎无法理解为什么这不起作用。如果我摆脱“InnerSubClass”,一切都会正常工作。

python 似乎不像其他语言那样提供“私有”类和函数,这很好,但我想利用嵌套至少将对象“集中”在一起。在这种情况下,除了“MainClass”中的函数之外,不应实例化“InnerClass”或“InnerSubClass”。

请提供有用的建议并解释为什么它不能按预期工作,并提供有关如何正确完成此操作的背景信息。如果真像看上去那么简单的话,现在应该已经弄清楚了。

编辑:为了澄清,这仅适用于 v2

use*_*343 5

查找顺序中没有“类范围”

创建新类时,将执行主体中的代码并将结果名称传递给type创建者。Python 查找从内部到外部,但是您没有“类级别”,只有您定义的名称以成为新类的属性/方法。事实上,如果您想访问方法内的类变量,您可以使用MyClass.attrsimple 来代替 simple attr

继承之所以有效,是因为继承InnerSubClass(InnerClass)发生在类创建内部。要在创建InnerClass后访问MainClass,请执行与类属性相同的操作:MainClass.InnerClass

仅举一个例子:

class Outer:
    out = 1
    class Inner:
        inside = 2
        try:
            print(out)  # this is confusing
        except NameError:
            print("can't find out")
        def f(self):
            try:
                print(inside)  # this is clear
            except NameError:
                print("can't find inside")
        try:
            print(Inner.inside)  # this is less clear
        except NameError:
            print("can't find Inner.inside")
Outer.Inner().f()
# can't find anything
Run Code Online (Sandbox Code Playgroud)

编辑:

上面是一个一般视图,要将其直接应用于您的情况,请像查看常规类属性一样查看您的内部类。您可以通过以下方式访问这些内容MyClass.attr,其中MyClass是全局定义的。如果替换attrInnerSubClass,您将获得该类(属性查找不关心继承,而是关心属性在哪里)。

带有嵌套继承类的精简示例:

class MainClass(object):
    class Inner(object):
        pass
    class InnerSub(Inner):
        def __init__(self):
            print(super(MainClass.InnerSub))  # note you use MainClass, known globally
    def f(self):
        return self.InnerSub()
MainClass().f()  # prints "<super ...>" and returns a MainCLass.InnerSub object
Run Code Online (Sandbox Code Playgroud)