当将类分配给实例变量时,自变量如何工作

时间:2019-01-11 19:22:34

标签: python robotframework

我在机器人框架中遇到了以下代码。 变量分配有不同的类名。 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. self.word = Foo;返回self.word.addition(self)
  2. self.word = Foo();返回self.word.addition()

2 个答案:

答案 0 :(得分:3)

问题出在def __init__(self)类内的Foo。您可以将参数self作为参数boo,但是不必像其他任何方法一样专门传递它。因此,在self.word = Foo(self)构造函数中,当您说__init__时,实际上是使用两个参数调用Foo中的self;您要传递的固有selfboo中的__init__() takes 1 positional argument but 2 were given。这就解释了为什么出现var grid = new WebGrid(source: Model.Stuff, defaultSort: "Stamp", rowsPerPage: 20, fieldNamePrefix: "wg_", canPage: true, canSort: true, pageFieldName: "pg"); <text> @grid.GetHtml(tableStyle: "gridtable", headerStyle: "gridtableheading", rowStyle: "gridtablerow", alternatingRowStyle: "gridtablerowalternate", columns: grid.Columns( grid.Column("View", format: (item) => (Html.ActionLink("Select", "View", "Item", new { itemID = item.ID }, null)), style: "padtable centeralign"), grid.Column("ID", "ID", style: "padtable rightalign"), grid.Column("CreatedDate", "Stamp", format: (item) => String.Format("{0:MM/dd/yyyy hh:mm tt}", item.CreatedDate), style: "padtable leftalign"), grid.Column("Type", "Type", style: "padtable rightalign"), grid.Column("Status", "Status", style: "padtable leftalign"), ), mode: WebGridPagerModes.Numeric) </text> 错误。

答案 1 :(得分:0)

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

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)

请注意,selfself的{​​{1}}参数有何不同。它被传递给__init__参数。这是因为python在构造类时会自动将variables作为第一个参数传递。