在Python中,没有开关/大小写。建议使用字典: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
实际上是自省的工具,它为您提供当前空间或给定对象中的局部变量-这不是使属性和变量准备好最终使用的好方法。
因此,您的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”。您可以使用类似C的“ switch”和Python中的纯“ 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.
...
虽然使用字典作为调用表是[[可能,并且具有在字典值中执行操作的功能,但此构造显然不是普通开关盒的“替代”-从指出“ case”函数不能在字典中内联编写,除非它们可以作为lambda函数编写,并且主要是他们将无法直接访问调用它们的函数上的变量。