首先,做这样的事情几乎总是一个坏主意。如果您想要这样做的唯一原因是确保您不打错字 - 有更好的工具(想想 IDE 或 pylint)。如果你 100% 肯定你需要这样的东西,这里有两种方法可以做到:
第一种方式 - 你可以用 using__setattr__
方法做到这一点。参见python__setattr__
文档
class Person(object):
def __init__(self, first_name, last_name):
self.__dict__['first_name'] = first_name
self.__dict__['last_name'] = last_name
def __setattr__(self, name, value):
if name in self.__dict__:
super(Person, self).__setattr__(name, value)
else:
raise AttributeError("%s has no attribute %s" %(self.__class__.__name__, name))
和输出:
In [49]: a = Person(1, 2)
In [50]: a.a = 2
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/usr/local/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 a.a = 2
/usr/local/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in __setattr__(self, name, value)
8 super(Person, self).__setattr__(name, value)
9 else:
---> 10 raise AttributeError("%s has no attribute %s" %(self.__class__.__name__, name))
AttributeError: Person has no attribute a
或者,您可以使用__slots__
(python__slots__
文档)执行此操作:
class Person(object):
__slots__ = ("first_name", "last_name")
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
输出:
In [32]: a = Person("a", "b")
In [33]: a.first_name
Out[33]: 'a'
In [34]: a.a = 1
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/usr/local/lib/python2.7/dist-packages/django/core/management/commands/shell.pyc in <module>()
----> 1 a.a = 1
AttributeError: 'Person' object has no attribute 'a'
第一种方法更灵活,因为它允许通过直接使用进一步破解此代码__dict__
,但这比现在更错误。第二种方法为一定数量的实例变量(引用)预分配空间,这意味着更少的内存消耗。