@Bjornie
Изучаю Python

Как динамически менять имена методов в Python?

Вопрос экпертам языка касается применения функций в валидациях Django, но на самом деле это вопрос чисто по языку Python. А именно: следуя принципу DRY я пытаюсь объединить на 99% похожий функционал в одну функцию и подключать ее где нужно.
В случае со строками, я бы наверное передал ее изначально как аргумент. Однако когда дело касается имен методов, полей и т.д. мне не понятно как это делается на уровне языка.

Вот пример:
def validator_team(self, field):
    if field:
            for i in field.member.all(): # 1. как вместо member подставить что-то другое?
                p = i.name # 2. как на место name динамически подставить, например, surname?
                do_something(p)
            ...
    return field

Надеюсь из этого простого примера понятно что я хотел бы сделать.
Повторюсь, если бы это были строки, то я отправил бы их аргументом, а имя аргумента подставлял в цикле.
  • Вопрос задан
  • 1008 просмотров
Решения вопроса 1
JaxxDexx
@JaxxDexx
https://docs.python.org/3/library/functions.html#g...

И тогда:
def validator_team(self, field, member='something', name='surname'):
    if field:
            for i in getattr(field, member).all():
                p = getattr(i, name)
                do_something(p)
            ...
    return field


Но вообще это говнокод)
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
longclaps
@longclaps
Это у тебя какой-то неправильный драй.
Правильный драй будет такой: написал что-то работающее - увидел повторяющийся фрагмент - вынес его в функцию - убедился, что стало короче и логичнее, и даже всё работает - успокоился.
А вот начинать с запихивания всего в одну мегафункцию не надо. Уже на трёхстрочном примере от JaxxDexx видно, какая это кака )
Ответ написан
lxsmkv
@lxsmkv
Test automation engineer
Не уверен что делать так хорошая идея, но это возможно, получая аттрибут объекта через getattr и обращаясь к результату.
class Member:
  def all(self):
    print "hello member"

class September:
  def all(self):
    print "hello september"
  

class Field:
  def __init__(self):
    self.member = Member()
    self.september = September()

field = Field()
field.member.all()
getattr(field, "september").all()

Если бы "september" было бы названием фунцкции то вызов был бы просто getattr(field, "september")()
По второму вопросу, все так же. А через setattr можно менять значение аттрибута. А через dir(field) можно получить список всех обьявленных на элементе полей.
class Member:
  def __init__(self):
    self.name = "John"
    self.surname = "Galt"
member = Member()
print member.name
print getattr(member, "surname")
setattr(member, "surname", "Wayne")
print getattr(member, "surname")
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы