2016-07-31 3 views
1

Я новичок в Python. Я получил код образца Python от поставщика программного обеспечения, который расширил свой программный API с помощью boost.python, поэтому мы можем назвать их в Python. Я путать с некоторыми из сегментов, таких как:Как установить подпроцесс переменной?

settings = zoo.AddAnimalSettings(carni_bird_list) 
settings.Name = 'birds' 
settings.Type = settings.Type.enum.Bird 
settings.water_min = 1, units.Litre 
settings.food_min = 10, units.Gram 

Все имена переменных заменяются быть эти забавные вещи в любом случае, просто для объяснения общей идеи.

Итак, проблема в третьей строке. Как мы можем установить переменную settings.Type с ее дополнительным свойством settings.Type.enum.Bird, где enum.Bird Я полагаю, что это какой-то перечислитель различных видов животных, который является под-свойством settings.Type?

Я попытался сделать некоторые испытания, чтобы добавить одну строку, следуя выше 5 строк, чтобы увидеть, если enum.Bird еще есть:

settings.Type = settings.Type.enum.Bird 

и он работает нормально. Итак, для этого экземпляра settings, его свойство sub Type не перезаписано его дополнительным свойством enum.Bird, оно все еще знает, что enum.Bird является его под-собственностью.

Можете ли вы посоветовать, нужно ли мне реализовать эту строку в Python, как я могу это сделать?

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

+1

Это действительно странный API, если то, что вы написали, действительно является репрезентативным для образцов кода поставщика. Мы можем сказать вам, что бы это обычно делалось, но если API действительно работает именно так, они, вероятно, создали нечто странное, что существенно изменило ситуацию. Вы уверены, что не смешивали два похожих имени или что-то еще? – user2357112

+0

О, спасибо! Я уверен, что я не смешивал подобные имена. Фактически поставщик использует этот метод повсеместно. –

+0

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

ответ

2

Я действительно не понимаю, в чем проблема. Рассмотрим Enum определено в Python:

import enum 


class Type(enum.Enum): 
    Bird = 0 
    Cat = 1 

Type.Bird и Type.Cat являются экземпляры из Type класса:

>>> Type.Bird 
<Type.Bird: 0> 
>>> Type.Cat 
<Type.Cat: 1> 

Как таковые, они имеют доступ к своему собственному классу, который Type:

>>> Type.Bird.__class__ 
<enum 'Type'> 

Теперь вы можете просто добавить property в Type классе и получить такое поведение:

class Type(enum.Enum): 
    Bird = 0 
    Cat = 1 

    @property 
    def enum(self): 
     return self.__class__ 

и теперь у вас есть:

>>> Type.Bird 
<Type.Bird: 0> 
>>> Type.Bird.enum 
<enum 'Type'> 
>>> Type.Bird.enum.Bird 
<Type.Bird: 0> 
>>> Type.Bird.enum.Cat 
<Type.Cat: 1> 

Обратите внимание, что в то время как выше позволяет писать Bird.enum не позволяет получить доступ в в Type.enum, потому что это вернет объект property.

Чтобы получить точное поведение, которое вы видите в этом коде вы можете:

  • Установите атрибут settings.Type быть экземпляром Type (возможно Invalid одного) и сделать:

    def AddAnimalSettings(*args) 
        settings = MyClass(*args) 
        settings.Type = Type.Bird 
        return settings 
    
  • Замените использование property специальным дескриптором, который будет обрабатывать доступ через класс. В этом случае прочитайте the documentation about property, который также предоставляет эквивалент своего кода на питоне. Случае вы должны изменить это __get__ когда obj is None:

    class MyProperty(object): 
    
        # omissis 
    
        def __get__(self, obj, objtype=None): 
         if obj is None: 
          return objtype # <-- changed this line 
         if self.fget is None: 
          raise AttributeError("unreadable attribute") 
         return self.fget(obj) 
    

    Используйте это как:

    class Type(enum.Enum): 
        Bird = 0 
        Cat = 1 
    
        @MyProperty 
        def enum(self): 
         return self.__class__ 
    

    А теперь у вас есть:

    >>> Type.enum 
    <enum 'Type'> 
    

    Type.enum.Bird так, что работает.

+0

Проблема заключается в том, что 'settings.Type' содержит или возвращает класс или пространство имен, которое содержит этот класс enum. –

+0

@ IgnacioVazquez-Abrams Я не понимаю вашего комментария. Я считаю, что начальное значение 'settings.Type' является только значением по умолчанию, поэтому это всего лишь один из экземпляров перечисления (они могут добавить дело« Неверный », который обрабатывается особенно). – Bakuriu

+0

Да, и это очень странно делать так. –

Смежные вопросы