Как работает собственная переменная, когда класс назначается переменным экземпляра - PullRequest
0 голосов
/ 11 января 2019

Я наткнулся на следующий фрагмент кода в рамках робота. Переменная присваивается с другим именем класса. 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 голосов
/ 14 января 2019

В вашей интерпретации происходящего есть пара неправильных вещей. Сначала давайте посмотрим на код и полученную ошибку:

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 принимает два параметра: self и variables:

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

Помните, что python автоматически передаст self, поэтому первый передаваемый аргумент будет связан с параметром variables.

Рассмотрим эту строку кода:

self.store = VariableStore(self)

На основании того, как определено VariableStore, оно точно такое же, как это:

self.store = VariableStore(variables=self)

Обратите внимание, что self не совпадает с параметром self __init__. Передается параметру variables. Это связано с тем, что python автоматически передает self в качестве первого параметра при создании класса.

0 голосов
/ 11 января 2019

Проблема def __init__(self) в классе Foo. У вас есть параметр self, но, как и любой другой метод, его не нужно специально передавать. Так что в конструкторе boo, когда вы говорите self.word = Foo(self), вы на самом деле вызываете __init__ из Foo с двумя аргументами; присущее self и self из boo, которое вы проходите. Это объясняет, почему вы получаете ошибку __init__() takes 1 positional argument but 2 were given.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...