Self не определен в аргументе метода класса

У меня 4 класса по несколько методов в каждом. Мне нужны эти методы, чтобы использовать некоторые переменные класса в качестве аргументов, например.

class Orange:
    def __init__(self,banana):
        self.banana = banana

    def apple(self,fruit=self.banana):
        return something

Я уже обнаружил, что это не работает, поскольку аргументы метода определяются при создании функции, а не при ее вызове, поэтому я нашел здесь обходной путь:

def apple(self,fruit=None):
    if fruit is None:
        fruit = self.banana

Но проблема в том, что у меня около 50 аргументов (нет в каждом методе, но сводка по всем методам всех классов), и, используя этот метод, я бы получил о сто новых строк кода, и мне кажется, что это очень обходной путь "грязный" ... нет какой-нибудь более простой способ достичь этого?

Кваргс поможет?
Madhan Varadhodiyil 07.08.2018 09:53

Не могли бы вы объяснить, что вы хотите делать со своими методами? Ваш пример немного странный ...

toti08 07.08.2018 09:53

ну, вы можете использовать условное выражение: fruit = self.banana if fruit is None else fruit. Так что ваши линии будут сокращены пополам. Я бы просто использовал полное заявление.

juanpa.arrivillaga 07.08.2018 09:56

Вы Конечно вам нужен метод с 50 (!) Аргументами?

Aran-Fey 07.08.2018 10:00
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
4
882
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Есть два способа решить эту проблему.

Опция 1

Используйте метод, который вы указали в формулировке проблемы, но, возможно, с тернарным оператором, чтобы сократить количество строк:

def apple(self, fruit=None):
    fruit = fruit if fruit is not None else self.banana

Вариант 2

Рассмотрите возможность пересмотра структуры вашего кода. Например, может не быть необходимости разрешать fruit, используемому в каждом методе, изменяться при вызове, а вместо этого просто использовать предустановленную опцию, такую ​​как self.banana. (По сути, просто удалите аргумент ключевого слова fruit и просто используйте вместо него self.banana.) Для тех, кому нужно изменять при вызове метода, используйте вариант 1.

Вариант 2 - лучший подход. Если у вас есть 50 аргументов, вы можете использовать * args или ** kwargs соответственно

Ravinder Baid 07.08.2018 10:45
Ответ принят как подходящий

Спасибо, ребята, благодаря вашим комментариям и ответам я нашел полное решение.

>>> class Orange:
...     def __init__(self,banana = "a"):
...         self.banana = banana
...     def apple(self,**kwargs):
...         self.__dict__.update(kwargs)
...         return self.banana
...
>>> test = Orange()
>>> test.apple()
'a'
>>> test.apple(banana = "b")
'b'

Как видите, передача другой ключевой переменной изменит результат именно так, как я хотел. Однако единственный недостаток (но он также может быть преимуществом, в зависимости от точки зрения) заключается в том, что это изменение является постоянным, поэтому, если мы снова вызовем функцию, она все равно изменится следующим образом:

>>> test.apple()
'b'

Но для меня это совсем не проблема. Если кто-то задается вопросом, как сделать эти изменения только временными, сохраните исходные значения инициализации в dict, а затем, когда вы захотите их использовать, обновите класс dict с переменной, в которой эти значения сохранены, как показано ниже:

>>> class Orange:
...     def __init__(self,fruit = {"banana":"a","cherry":"b"}):
...         self.fruit=fruit
...     def apple(self,**kwargs):
...         self.__dict__.update(self.fruit)
...         self.__dict__.update(kwargs)
...         return self.banana
...
>>> test = Orange()
>>> test.apple()
'a'
>>> test.apple(banana = "b")
'b'
>>> test.apple()
'a'

Self.fruit хранит исходную информацию и обновляет переменные класса в начале функции. Если что-то находится в kwargs, оно просто отменяет это.

Лучший вариант - сделать для него отдельный мутатор.

def setFruit(self, fruit):
    self.fruit = fruit

Другие вопросы по теме