class A(object):
def __nikunj__(self):
print("Inside :: A")
def __nike__(self):
print("Something")
class B(A):
def __nike__(self):
print("inside :: B")
super(B,self).__nike__()
object_B = B()
print(object_B.__nike__())
上面的代码工作正常。
class A(object):
def __nikunj__(self):
print("Inside :: A")
def __nike__(self):
print("Something")
class B(A):
test = super(B,self).__nike__()
def __nike__(self):
print("inside :: B")
object_B = B()
print(object_B.test)
此代码抛出错误:
Traceback (most recent call last):
File "C:\Users\Nikunj Parmar\AppData\Local\Programs\Python\Python36 \test_test.py", line 7, in <module>
class B(A):
File "C:\Users\Nikunj Parmar\AppData\Local\Programs\Python\Python36\test_test.py", line 8, in B
test = super(B,self).__nike__()
NameError: name 'B' is not defined
为什么呢?我不明白为什么它表明找不到B(在第二种情况下)。
答案 0 :(得分:1)
在对象存在(即类本身或其实例)之后调用(即执行)方法。
在调用时间__nike__
的1 st 示例中,已定义B
类。类的主体中的语句在类的定义时间内执行。在2 nd 示例中,在执行test = super(B,self).__nike__()
时,不存在类B
,因为在第一次定义类时执行此行
在以下行中可以观察到相同的行为:d = {'a': 1, 'b': d['a']}
。
NameError: name 'd' is not defined
结果为d
,因为我们在尝试访问d['a']
时尚未定义<div class="col-md-12">
<div class="col-md-4" >
...
</div>
<div class="col-md-4" >
...
</div>
</div>
。
不要将dunder名称用于任意方法。
答案 1 :(得分:1)
在评估类主体时,尚未创建类对象。
根据docs:
当输入类定义时,会创建一个新的命名空间,并将其用作本地范围 - 因此,对局部变量的所有赋值都将进入此新命名空间。特别是,函数定义在此处绑定新函数的名称。
当正常保留类定义(通过结尾)时,会创建一个类对象。这基本上是类定义创建的命名空间内容的包装器;我们将在下一节中详细了解类对象。恢复原始本地范围(在输入类定义之前生效的范围),并且类对象在此绑定到类定义标题中给出的类名(示例中为
ClassName
)。
您可能需要阅读whole page。它准确地解释了类的命名空间是如何工作的,以及什么时候创建的。
第一个版本因LEGB评估而起作用。评估方法代码,但在定义方法时不调用。在方法中使用B
编译为&#34;找到名称B&#34;。在您实际调用该方法之前,该名称不必存在。当您最终执行代码时,名称A
和B
已经绑定到全局命名空间中的类(LEGB中的G),并且一切正常。
最后,请记住,使用双下划线(dunder)方法(a.k.a。special methods或魔术方法)在Python中是非常不受欢迎的。这些方法用于运算符重载的目的,并且所有这些名称都是自动保留的。来自docs:
任何使用
__*__
名称,在任何情况下,如果没有明确记录使用,都会在没有警告的情况下破损。
由于您不熟悉Python,我尝试发布一些链接供您遵循,并提及一些在该语言中无处不在的基本概念。希望能在将来帮助你。