Ваши варианты делятся на две значительные категории: вы либо скопировать атрибуты из _CarType
в Car
, или установить метаклассом Car
«s к обычаю один с __getattr__
метода, который делегирует _CarType
(так что это не совсем верно, что вы не может использовать __getattr__
: вы можете, вам просто нужно положить в meta класс, а не в Car
сам ;-).
Второй вариант имеет последствия, которые вы могли бы найти Свой (если они специально не желательно): атрибуты не отображаются на dir(Car)
, и они не могут быть доступны на например из Car
, только на Car
себя. То есть:
>>> class MetaGetattr(type):
... def __getattr__(cls, nm):
... return getattr(cls.types, nm)
...
>>> class Car:
... __metaclass__ = MetaGetattr
... types = _CarType
...
>>> Car.GAS_CAR_ENGINE
1
>>> Car().GAS_CAR_ENGINE
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Car' object has no attribute 'GAS_CAR_ENGINE'
Вы могли бы исправить «не из экземпляра» вопрос по также Добавление __getattr__
к Car
:
>>> class Car:
... __metaclass__ = MetaGetattr
... types = _CarType
... def __getattr__(self, nm):
... return getattr(self.types, nm)
...
сделать оба вида поиска работы, как это, вероятно, ожидается:
>>> Car.GAS_CAR_ENGINE
1
>>> Car().GAS_CAR_ENGINE
1
Однако, определяя два, по существу, равна __getattr__
s, не кажется элегантным.
Поэтому я подозреваю, что более простой подход, «скопировать все атрибуты», является предпочтительным. В Python 2.6 или лучше, это является очевидным кандидатом на класс декоратора:
def typesfrom(typesclass):
def decorate(cls):
cls.types = typesclass
for n in dir(typesclass):
if n[0] == '_': continue
v = getattr(typesclass, n)
setattr(cls, n, v)
return cls
return decorate
@typesfrom(_CarType)
class Car(object):
pass
В общем, это стоит определение декоратора, если вы используете его больше, чем один раз; если вам нужно выполнить эту задачу только для одного класса, то вместо этого вместо этого следует добавить код inline (после инструкции class
).
Если вы застряли с Python 2.5 (или даже 2,4), вы можете определить typesfrom
таким же образом, вы просто применить его в несколько менее элегантной материи, т.е. Car
определение становится:
class Car(object):
pass
Car = typesfrom(_CarType)(Car)
Помните, что синтаксис декоратора (представленный в 2.2 для функций, в 2.6 для классов) - это просто удобный способ обернуть эти важные и часто повторяющиеся семантики.
Почему вы не можете использовать '__getattr__'? Похоже, это самое простое решение. (проверка на isupper и do 'getattr (_CarType, key)') – kibitzer