Python объявляет объектные функции при инициализации

#python

#python

Вопрос:

Предположим, у меня есть класс, которому передан набор параметров.

Например:

 class Thing(object): 
    def __init__(self, options): 
        self.name = options['name']
        if options['material'] == 'organic': 
            self.living = options['living'] 
            if self.living: 
                self.kingdom = options['kingdom'] 
        else:
            self.material = options['material'] 
  

Поэтому, если он материальный и органический, у него будет дополнительная опция, указывающая, является ли он живым, если он живой, у него также будет королевство и т.д.

Предположим, я хочу определить функцию в class Thing , которая будет, например:

 def belongToKingdom(self): 
    print self.kingdom
  

Но я хочу, чтобы такая функция была определена только в __init__ , если kingdom передается в options, в противном случае игнорируется. Каков правильный способ добиться этого?

Комментарии:

1. Есть подкласс class LivingThing(Thing): ?

2. Да, я знаю, это должен был быть просто упрощенный пример, фактический вариант использования немного отличается, потому что есть набор функций, который динамически генерируется из массива парных значений. Поэтому я не могу просто создавать подклассы для каждой возможной комбинации пар, мне на самом деле нужно взять стандартную функцию-прототип и сгенерировать ее с несколькими переменными, определяемыми парами значений.

Ответ №1:

 class Thing(object):
    def __init__(self, **options):
        if options.get('living',None):
            def belongToKingdom(self):
                print(self.kingdom)
            self.kingdom = options['kingdom']
            self.belongToKingdom = belongToKingdom
  

Комментарии:

1. Это может подойти для другого вопроса, но предположим, я не знаю, какая функция, которую я хочу определить, будет вызвана, есть ли способ форматировать имя функции в формате str? Т.е. рабочий эквивалент для self.belongTo{0}.format(options[‘kingdom’]) <который, возможно, всегда возвращал бы True, но в любом случае>

2. @user3467349 Я действительно не могу понять, о чем вы спрашиваете, но звучит так, как будто вы пытаетесь поместить значимые данные в имена переменных. Не делайте этого! Вместо этого просто создайте список опций, so Thing().options возвращает {'living':True, 'kingdom':"Animal", ... } и проверяет его

3. @user3467349 но, конечно, на самом деле есть способ сделать именно то, что вы хотите. Вместо манипулирования self , манипулируйте self.__dict__ . Тогда вы можете использовать строку вместо имени переменной. Например: self.__dict__["belongTo{}".format('kingdom')] = lambda self: print(self.kingdom) работает (это просто уродливее, чем sin)

4. Да, я как раз думал об этом. Я мог бы также просто создать новый словарь правильно, т. Е. self.printMyAttribute = {}, а затем добавить в него, чтобы он выглядел как {‘kingdom’: <королевство функций> } и т.д. Есть ли причина, по которой вы бы препятствовали чему-то подобному?

5. @AdamSmith это не сработает; belongToKingdom это функция, которая не совсем совпадает с методом. from types import MethodType Затем вам нужно выполнить присваивание self.belongToKingdom = MethodType(belongToKingdom, self)