Сокращение синтаксических ошибок, когда метод обращается к переменным экземпляра? - PullRequest
0 голосов
/ 16 мая 2018

Следующий код представляет собой упрощенный пример задачи, над которой я работаю, с использованием Python, которая кажется естественным образом подходящей для стиля ООП:

class Foo:
  def __init__(self):
    self.x = 1
    self.y = 1
    self.z = 1
  def method(self):
    return bar(self.x,self.y,self.z)

def bar(x,y,z):
  return x+y+z

f = Foo()
print(f.method())

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

return bar(self.a.self.b,self.c,self.d,self.e,self.f,self.g,self.h,self.i)

Ух ты, было бы неплохо написать это в стиле, похожем на этот:

return bar(a,b,c,d,e,f,g,h,i)

Это было бы намного более лаконично иудобочитаемый.Один из способов сделать это - переписать строку так, чтобы она принимала объект Foo в качестве входных данных, а не набор скалярных переменных, но я бы предпочел этого не делать.На самом деле, это просто подтолкнуло бы синтаксическую ошибку в функцию bar, где, я думаю, у меня был бы код, который выглядел бы так:

  def bar(f):
    return f.a+f.b+f.c

Есть ли лучший способ справиться с этим?Насколько я понимаю, без «я» я бы ссылался на переменные класса, а не на переменные экземпляра.Я думал об использовании словаря, но это кажется еще более грубым, со всеми ["a"] вещами.Может ли быть какой-то автоматизированный способ взять словарь с ключами типа "a", "b", "c", ... и разгрузить значения в локальные переменные с именами a, b, c и т. Д.?

Ответы [ 3 ]

0 голосов
/ 16 мая 2018

Вы можете использовать __dict__ для создания атрибутов из данных различной длины, а затем использовать classmethod для суммирования переданных атрибутов:

import string
class Foo:
  def __init__(self, data):
    self.__dict__ = dict(zip(string.ascii_lowercase, data))
  @classmethod
  def bar(cls, instance, vals = []):
    return sum(instance.__dict__.values()) if not vals else sum(getattr(instance, i) for i in vals)

f = Foo(range(20))
print(Foo.bar(f))
print(Foo.bar(f, ['a', 'c', 'e', 'k', 'm']))

Выход:

190
28
0 голосов
/ 16 мая 2018

Я думаю, вы поступаете неправильно.Вы правы в том, что ваши примеры трудно читать, но я не думаю, что основной причиной является синтаксис Python.Список аргументов, содержащий 10-15 переменных, будет трудно прочитать на любых языках программирования.Я думаю, что проблема в структуре вашей программы.Вместо того, чтобы пытаться найти способы обойти синтаксис и соглашения Python, попробуйте реорганизовать вашу программу, чтобы вашим классам не требовалось так много атрибутов, или реорганизовать ваши методы, чтобы им не нужно было возвращать так много атрибутов.

К сожалению, я не могу помочь вам сделать это, не увидев полную версию вашего кода, но Stack Review Code Exchange был бы хорошим местом, чтобы получить некоторую помощь в этом.Сокращение количества возвращаемых значений и , не предусматривающих нестандартных способов составления списков и управления вашими атрибутами, сделает ваш код более легким для чтения и обслуживания как для других, так и для вас самих в будущем.

0 голосов
/ 16 мая 2018

Ну, вы могли бы сделать это так, если бы вы действительно этого хотели, но я бы посоветовал против этого.Что если вы добавите поле в свой класс и так далее?Также это только усложняет ситуацию.

class Foo:
  def __init__(self):
    self.x = 1
    self.y = 1
    self.z = 1
  def method(self):
    return bar(**vars(self))  # expand all attributes as arguments

def bar(x,y,z):
  return x+y+z

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