我正在使用元类为这样的新类创建属性:class Property(object):
def __init__(self, internal_name, type_, default_value):
self._internal_name = internal_name
self._type = type_
self._default_value = default_value
def generate_property(self):
def getter(object_):
return getattr(object_, self._internal_name)
def setter(object_, value):
if not isinstance(value, self._type):
raise TypeError("Expect type {0}, got {1}.".format(self._type, type(value)))
else:
setattr(object_, self._internal_name, value)
return property(getter, setter)
class AutoPropertyMeta(type):
def __new__(cls, name, bases, attributes):
for name, value in attributes.iteritems():
if isinstance(value, Property):
attributes[name] = value.generate_property()
return super(AutoPropertyMeta, cls).__new__(cls, name, bases, attributes)
这样我就可以写这样的代码:
^{pr2}$
而不是:class SomeClassWithALotAttributes(object):
def __init__(self):
self._attribute_a = 0
...
self._attribute_z = 1.0
def get_attribute_a(self):
return self._attribute_a
def set_attribute_a(self, value):
if not isinstance(value, int):
raise TypeError("Expect type {0}, got {1}.".format(self._type, type(value))
else:
self._attribute_a = value
attribute_a = property(get_attribute_a, set_attribute_a)
...
如果您总是在获取属性值之前设置值,那么它会非常有效,因为AutoPropertyMeta只生成getter和{}方法。实际实例属性是在第一次设置该值时创建的。所以我想知道是否有一种方法可以通过元类为类创建实例属性。在
下面是我现在使用的一种解决方法,但我总是想知道是否有更好的方法:class Property(object):
def __init__(self, internal_name, type_, default_value):
self._internal_name = internal_name
self._type = type_
self._default_value = default_value
def generate_property(self):
def getter(object_):
return getattr(object_, self._internal_name)
def setter(object_, value):
if not isinstance(value, self._type):
raise TypeError("Expect type {0}, got {1}.".format(self._type, type(value)))
else:
setattr(object_, self._internal_name, value)
return property(getter, setter)
def generate_attribute(self, object_):
setattr(object_, self._internal_name, self._default_value)
class AutoPropertyMeta(type):
def __new__(cls, name, bases, attributes):
property_list = []
for name, value in attributes.iteritems():
if isinstance(value, Property):
attributes[name] = value.generate_property()
property_list.append(value)
attributes["_property_list"] = property_list
return super(AutoPropertyMeta, cls).__new__(cls, name, bases, attributes)
class AutoPropertyClass(object):
__metaclass__ = AutoPropertyMeta
def __init__(self):
for property_ in self._property_list:
property_.generate_attribute(self)
class SomeClassWithALotAttributes(AutoPropertyClass):
attribute_a = Property("_attribute_a", int, 0)