当类分配给实例变量时,self变量是如何工作的



我在机器人框架中遇到了以下代码。 变量被分配了不同的类名。 https://github.com/robotframework/robotframework/blob/master/src/robot/variables/variables.py

def __init__(self):
self.store = VariableStore(self)
self._replacer = VariableReplacer(self)
self._finder = VariableFinder(self.store)

为了理解上面的赋值是如何工作的,我写了以下一段代码,在使用self时抛出错误

class Foo(object):
def __init__(self):
pass
def addition(self):
return 5
class boo(object):
def __init__(self):
self.word = Foo(self)  
def multiply(self):
return self.word.addition()
if __name__ == '__main__':
b = boo()
print(b.multiply())  #TypeError: __init__() takes 1 positional argument but 2 were given

在 boo() 类中使用以下组合时,获得正确的输出,即 5。

  1. 自我.单词=Foo;返回 self.word.addition(self)
  2. self.word=Foo();返回 self.word.addition()

该问题def __init__(self)Foo类中。你有参数self,但是,就像任何其他方法一样,它不必专门传入。所以在boo构造函数中,当你说self.word = Foo(self)时,你实际上是在用两个参数调用Foo__init__;你通过的固有selfbooself。这就解释了为什么您会收到错误__init__() takes 1 positional argument but 2 were given.

你对正在发生的事情的解释有几点错误。首先,让我们看一下代码和您收到的错误:

b = boo()
print(b.multiply())  #TypeError: __init__() takes 1 positional argument but 2 were given

您的评论似乎暗示您认为当您调用b.multiply()时发生了错误。但是,当您查看堆栈跟踪时,您会发现它发生在您执行以下b = boo()

Traceback (most recent call last):
File "/tmp/junk.py", line 16, in <module>
b = boo()
File "/tmp/junk.py", line 10, in __init__
self.word = Foo(self)  
TypeError: __init__() takes 1 positional argument but 2 were given

请注意,堆栈跟踪会准确地告诉您问题所在。您已经定义了Foo.__init__来采用单个参数,但给出了两个参数。为什么要给两个?当你在python中创建类的实例时,python会自动传入self参数。换句话说,如果你做b=boo(),你的函数将自动获得self,而不必你显式地传入它。这是python设计的一个非常基本的一部分。它与机器人框架无关。

在尝试复制机器人代码时,您创建了一个名为Foo的类,该类采用名为self的单个参数。但是,VariableStore对象采用两个参数:selfvariables

class VariableStore(object):   
def __init__(self, variables):
...

请记住,python 会自动传入self,因此您传入的第一个参数将与variables参数相关联。

考虑以下代码行:

self.store = VariableStore(self)

根据VariableStore的定义方式,它与以下内容完全相同:

self.store = VariableStore(variables=self)

请注意self__init__self参数不同。它被传递给variables参数。这是因为 python 在构造类时会自动传递self作为第一个参数。

最新更新