这很简单,但知道你为什么要这样做会很有帮助。最 Pythonic 的方法可能是拥有一个创建所有访问器函数的元类。如果您尝试正确执行此操作,我会查找 python property 范例。但是,如果您的所有访问器功能都相同,为什么您需要为它们提供单独的功能呢?您可以通过以下方式轻松设置值:
x = Object()
x.value = value
...只要你省去完全不必要的双下划线,至少。如果您确实需要更改对每个属性的每次调用,您可以覆盖 __setattr__ (Python Data Model Reference)。附带说明一下,在我合作过的每个小组中,都非常不鼓励使用 __variable 方法。它不会阻止任何人实际访问该值(您可以通过 instance._Object__value1 进行操作),但它会使子类化变得可怕。
如果您只想对每个属性获取或设置进行相同的预处理,您总是可以执行以下操作:
class Object:
_ATTR_NAMES = ('value1', 'value2', ...)
def __init__(self):
for name in self._ATTR_NAMES:
setattr(self, "_" + name, None)
def set_attr(self, name, value):
if name in self._ATTR_NAMES:
setattr(self, name[1:], value)
else:
raise AttributeError("No attribute named %s found"%name)
Python 的 setattr 是一个在属性上设置具有给定名称的属性的函数。在这种情况下,您可以简单地拥有一个属性列表,在此基础上设置它们,然后使用相应的“getattr”函数检索它们。不过,我再次警惕您这样做的原因。通常显式优于隐式。很少很难只做一个额外的 get/set 函数来使引用更加清晰。
如果你真的需要,你也可以使用与我刚刚展示的属性非常相似的技术生成 get/set 函数(即,动态创建包装 set_attr 的函数),但同样,它通常会生成代码更难维护和阅读。除非您确实有强烈而明确的需要,否则我会避免使用其中的许多技术。如果你真的必须这样做,这样的事情会起作用:
class Object:
_ATTR_NAMES = ('value1', 'value2', ...)
def __init__(self):
for name in self._ATTR_NAMES:
setattr(self, "_" + name, None)
def _set_attr(self, name, value):
if name in self._ATTR_NAMES:
setattr(self, name[1:], value)
else:
raise AttributeError("No attribute named %s found"%name)
# This binds named set functions to the class
for name in Object._ATTR_NAMES:
def tempSetter(self, value):
self._set_attr(name, value)
setattr('set_'+name, tempSetter)
del name
del tempSetter
这是一种很老套的做法。在元类中进行这种处理更为优雅。但是,由于需要大量背景知识才能理解,因此我将跳过该内容。如果您需要在每个 set 函数之前进行预处理,通常更倾向于按照以下方式进行操作:
def _preprocessing(self, value):
# Do something here
return value
def set_value1(self, value):
value = self._preprocessing(value)
self._value1 = value
def set_value2(self, value):
value = self._preprocessing(value)
self._value2 = value
最后,如果您担心的只是生成样板 get/set 函数的时间,那么只需编写一个脚本,将您的 Python 类的骨架写为文本文件。我有这些类型的脚本,它们基于原始模块概述了我的单元测试用例。或者在您的文本编辑器中有一个脚本宏。读代码的次数比写代码的次数多,所以不要为了省去几次按键而编写复杂的代码。