Python get @ property.setter оформленный метод в классе - PullRequest
1 голос
/ 17 апреля 2020

В Python нет переключателя / корпуса. Рекомендуется использовать словари: Что является эквивалентом Python для оператора case / switch?

в Python Рекомендуется использовать @property для реализации getter / setter: Как Pythoni c способ использовать геттеры и сеттеры?

Итак, если я хочу создать класс со списком свойств для переключения, чтобы я мог получать или обновлять значения Я могу использовать что-то вроде:

class Obj():                                                                                          
"""property demo"""                                                                                  

    @property                                                                                
    def uno(self):                                                                                              
        return self._uno                                                                                       
    @uno.setter                                                                                
    def uno(self, val):                                                                            
        self._uno = val*10                                                                                   

    @property                                                                                          
    def options(self):                                                                                        
        return dict(vars(self))   

Но при вызове

o=Obj()
o.uno=10 # o.uno is now 100
o.options

я получаю {'_uno': 100}, а не {'uno': 100}. Я что-то упустил?

1 Ответ

2 голосов
/ 17 апреля 2020

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

Итак, ваш options код должен быть немного более сложным - один из способов go - это поиск в классе любых свойств, а затем использование getattr для получения значений этих свойств, но с использованием getter кодировать и анализировать переменные экземпляра, чтобы получить любые методы, непосредственно приписанные, но отбросить те, которые начинаются с _:


    @property                                                                                          
    def options(self):            
        results = {}
        # search in all class attributes for properties, including superclasses:
        for name in dir(self.__class__):
            # obtain the object taht is associated with this name in the class
            attr = getattr(self.__class__, name)
            if isinstance(attr, property):   
                # ^ if you want to also retrieve other "property like"
                # attributes, it is better to check if it as the `__get__` method and is not callable:
                # "if hasattr(attr, '__get__') and not callable(attr):"

                # retrieves the attribute - ensuring the getter code is run:
                value = getattr(self, name)
                results[name] = value
        # check for the attributes assigned directly to the instance:
        for name, value in self.__dict__.items():
            # ^ here, vars(self) could have been used instead of self.__dict__ 
            if not name.startswith("_"):
                results[name] = value

        return results   

о switch..case

В дополнение к вашему вопросу относительно конструкции "switch ... case": пожалуйста, не обращайте внимания на весь прочитанный вами контент, говоря, что "в Python следует использовать словари вместо switch / case". Это неверно.

Правильная конструкция для замены «switch ... case» в Python - это «if..elif..else». Вы можете получить всю выразительность, которая есть у C -подобного «переключателя» с простым деревом «if-else» в Python, и на самом деле, go намного выше этого, как тестовое выражение в if...elif может быть произвольным, а не просто совпадающим значением.

option = get_some_user_option()
if option == "A":
   ...
elif option == "B":
   ...
elif option in ("C", "D", "E"):
   # common code for C, D, E
   ...
   if option == "E":
        # specialized code for "E",  
else:
   # option does not exist.
   ...

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

...