外部 class 如何从其内部 class 访问数据?
How can an outer class access data from its inner class?
我试图更好地理解如何使用基于 this question/answer 的非常简单的测试用例来使用子 classes。
class Outer():
def __init__(self, x):
self.x = super(Inner, self).__init__
# self.x = Inner(**kwargs)
def add_two(self):
""" """
return self.x + 2
class Inner():
def __init__(self, x=2):
self.x = x
res = Outer(x=3).add_two()
# res = Outer({'x' : 3}).add_two()
print(res)
>> NameError: name 'Inner' is not defined
如果我 运行 相同的代码,但使 Inner()
成为自己独立的 class(与 Outer()
的子 class 相对,我收到以下错误。
TypeError: super(type, obj): obj must be an instance or subtype of type
此错误的原因是什么,我该如何解决?
在Python(或其他语言)中嵌套classes 很少有意义。在这种情况下,它根本没有任何用处。
如果在 "Outer" class 上你想要一个 "Inner" 的关联实例,那应该作为实例属性创建,在 __init__
方法上外部 - 像这样:
class Outer():
def __init__(self, x):
self.x = Inner(x)
# self.x = Inner(**kwargs)
def add_two(self):
""" """
return self.x + 2
class Inner():
def __init__(self, x=2):
self.x = x
现在,逐步查看您的原始代码,并尝试更好地理解为什么它不起作用:
在 Python 中,在 class 的主体中声明的所有内容都成为 class 的属性 - 它的单个副本将(通常)由 class 的所有实例共享.声明一个整体 class 嵌套在句法上是合法的,但对你没有任何好处:内部 class 在任何意义上都不是来自外部世界的 "hidden" 语言:不是语言,也不是Python 开发人员通常遵循的约定。
如果您希望用户(即其他程序员,或您自己在使用此文件的代码中)创建 "Outer" 的实例并避免创建 "Inner" 的实例,只需在其前缀带有 _
的名称。这是 Python 代码中的约定,开发人员通常会知道他们不应该相信任何 class、函数或以单个 _
开头的其他名称可以安全地用于第 3 方代码 - 这是最接近 Python 的 "private" 或 "protected" 成员。
现在开始:
...
self.x = super(Inner, self).__init__
这又没有意义。 super
或显式引用 superclass 是为了调用 superclasses - 即,您继承的 classes。您在代码中没有创建继承关系,而是创建了一种组合关系。这就是您收到该错误消息的原因 - 如果您使用的是 super 的显式版本,则您传递的对象必须是您调用 super
的 class 的子 class。这里不是这种情况。 (此外,以这种形式进行,它不调用方法 - 只是引用它 - 所有函数或方法调用都是通过使用 ()
)
您还可以使 Outer 继承自 Inner - 在这种情况下,Outer 将 "be" 成为一个 Inner,无需在属性中保留对它的引用 - self
将意味着两个 Outer和一个内部 class。
在这种情况下,我们在解析"Outer"的声明时需要引用"Inner",所以需要先定义:
class _Inner():
def __init__(self, x=2):
self.x = x
class Outer(_Inner):
def __init__(self, x):
super().__init__(x)
def add_two(self):
""" """
return self.x + 2
注意无参数的使用super
——对Python的主要改动之一 3.如果你需要写的代码仍然兼容Python 2,将参数改为super即可是明确的,调用将是 super(Outer, self).__init__()
.
(同样,调用它 _Inner
将意味着您的 class 的用户不应该从 _Inner
继承或实例化,而应该使用 Outer
- 这是一个编码风格的约定而不是语言语法)
我试图更好地理解如何使用基于 this question/answer 的非常简单的测试用例来使用子 classes。
class Outer():
def __init__(self, x):
self.x = super(Inner, self).__init__
# self.x = Inner(**kwargs)
def add_two(self):
""" """
return self.x + 2
class Inner():
def __init__(self, x=2):
self.x = x
res = Outer(x=3).add_two()
# res = Outer({'x' : 3}).add_two()
print(res)
>> NameError: name 'Inner' is not defined
如果我 运行 相同的代码,但使 Inner()
成为自己独立的 class(与 Outer()
的子 class 相对,我收到以下错误。
TypeError: super(type, obj): obj must be an instance or subtype of type
此错误的原因是什么,我该如何解决?
在Python(或其他语言)中嵌套classes 很少有意义。在这种情况下,它根本没有任何用处。
如果在 "Outer" class 上你想要一个 "Inner" 的关联实例,那应该作为实例属性创建,在 __init__
方法上外部 - 像这样:
class Outer():
def __init__(self, x):
self.x = Inner(x)
# self.x = Inner(**kwargs)
def add_two(self):
""" """
return self.x + 2
class Inner():
def __init__(self, x=2):
self.x = x
现在,逐步查看您的原始代码,并尝试更好地理解为什么它不起作用: 在 Python 中,在 class 的主体中声明的所有内容都成为 class 的属性 - 它的单个副本将(通常)由 class 的所有实例共享.声明一个整体 class 嵌套在句法上是合法的,但对你没有任何好处:内部 class 在任何意义上都不是来自外部世界的 "hidden" 语言:不是语言,也不是Python 开发人员通常遵循的约定。
如果您希望用户(即其他程序员,或您自己在使用此文件的代码中)创建 "Outer" 的实例并避免创建 "Inner" 的实例,只需在其前缀带有 _
的名称。这是 Python 代码中的约定,开发人员通常会知道他们不应该相信任何 class、函数或以单个 _
开头的其他名称可以安全地用于第 3 方代码 - 这是最接近 Python 的 "private" 或 "protected" 成员。
现在开始:
...
self.x = super(Inner, self).__init__
这又没有意义。 super
或显式引用 superclass 是为了调用 superclasses - 即,您继承的 classes。您在代码中没有创建继承关系,而是创建了一种组合关系。这就是您收到该错误消息的原因 - 如果您使用的是 super 的显式版本,则您传递的对象必须是您调用 super
的 class 的子 class。这里不是这种情况。 (此外,以这种形式进行,它不调用方法 - 只是引用它 - 所有函数或方法调用都是通过使用 ()
)
您还可以使 Outer 继承自 Inner - 在这种情况下,Outer 将 "be" 成为一个 Inner,无需在属性中保留对它的引用 - self
将意味着两个 Outer和一个内部 class。
在这种情况下,我们在解析"Outer"的声明时需要引用"Inner",所以需要先定义:
class _Inner():
def __init__(self, x=2):
self.x = x
class Outer(_Inner):
def __init__(self, x):
super().__init__(x)
def add_two(self):
""" """
return self.x + 2
注意无参数的使用super
——对Python的主要改动之一 3.如果你需要写的代码仍然兼容Python 2,将参数改为super即可是明确的,调用将是 super(Outer, self).__init__()
.
(同样,调用它 _Inner
将意味着您的 class 的用户不应该从 _Inner
继承或实例化,而应该使用 Outer
- 这是一个编码风格的约定而不是语言语法)