Задать вопрос
@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

Надеюсь из этого простого примера понятно что я хотел бы сделать.
Повторюсь, если бы это были строки, то я отправил бы их аргументом, а имя аргумента подставлял в цикле.
  • Вопрос задан
  • 1106 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 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")
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы
Strikt Москва
от 100 000 до 180 000 ₽
ITK academy Саратов
от 75 000 ₽
Sim-Ba Pay Санкт-Петербург
от 180 000 ₽