【问题标题】:Python get @property.setter decorated method in a classPython 获取类中的@property.setter 修饰方法
【发布时间】:2020-07-30 23:40:29
【问题描述】:

在 Python 中没有 switch/case。建议使用字典:What is the Python equivalent for a case/switch statement?

在 Python 中,使用 @property 来实现 getter/setter 是一种很好的做法:What's the pythonic way to use getters and setters?

因此,如果我想构建一个具有要切换的属性列表的类,以便我可以获取或更新值,我可以使用类似的东西:

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}。 我错过了什么吗?

【问题讨论】:

  • 属性不包含在vars 中,因为它们不在实例__dict__ 中。您只看到支持属性。但我不清楚您所说的“要切换的属性列表” 是什么意思,所以很难说正确的实现可能是什么。

标签: python-3.x class properties switch-statement decorator


【解决方案1】:

vars 确实是一种自省工具,它为您提供当前空间或给定对象中的局部变量 - 这不是获取属性和变量以供最终使用的好方法。

因此,您的 options 代码必须更复杂一些 - 一种方法 是在类中搜索任何属性,然后使用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”。这是不正确的。

在 Python 中替换“switch...case”的正确结构是“if..elif..else”。你可以在 Python 中使用类似 C 的“switch”和一个普通的“if-else”树来拥有所有的表现力,实际上,远远不止于此,因为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.
   ...

虽然可能使用字典作为调用表,并且具有在字典值中执行操作的函数,但这种构造显然不是普通 switch 案例的“直接”替代品- 从“case”函数不能在字典中内联写入这一点开始,除非它们可以写成 lambda 函数,主要是 他们将无法直接访问调用它们的函数上的变量。

【讨论】:

    猜你喜欢
    • 2020-04-07
    • 2019-09-01
    • 2020-04-06
    • 2020-08-20
    • 2015-02-14
    • 2011-07-01
    • 1970-01-01
    相关资源
    最近更新 更多