2013-03-28 2 views
1

Просто после чего-то из примера, который я нашел, чтобы интегрироваться с частью проекта, где я создаю большое количество классов, подклассифицированных из «Что-то» ниже, и я пытаюсь сделайте шаги к более автоматическому созданию этих элементов без необходимости писать их каждый раз (потому что количество элементов становится большим, и я могу уменьшить количество шаблонов, перейдя в меньший список атрибутов, то есть суть по крайней мере).attibutes классов подкласса в реестре классов подкласса

Во всяком случае, учитывая:

class SomethingMeta(type): 
    def __init__(cls, name, bases, dct): 
     if not hasattr(cls, 'registry'): 
      cls.registry = {} 
     else: 
      interface_id = name.lower() 
      cls.registry[interface_id] = cls 

     super(SomethingMeta, cls).__init__(name, bases, dct) 

class Something(object): 
    __metaclass__ = SomethingMeta 

class SomethingA(Something): 
    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

class SomethingB(Something): 
    def __init__(self, z=0): 
     self.z = z 

Так что у меня реестра Something.registry классов, созданных с помощью «Что-то» ... но то, что я действительно хочу сделать, это получить список атрибутов Класс «Что-то» подклассифицирован в «SomethingMeta». Поэтому в Something.registry необходимо зафиксировать атрибуты зарегистрированного подкласса, даже определенные, т. Е. Мне нужно знать, что когда SomethingB зарегистрирован, что на нем есть SomethingB.z, поэтому я могу получить отпечаток класс подкласса для ввода словаря. Только я, похоже, не могу точно сказать, что мне нужно.

Любой вход оценили, могут быть предоставлены разъяснения, может сказать, что именно я пытаюсь делать, если я делаю это неправильно, и т.д.

EDIT:

Хотела результата. В целом я хотел бы:

1) передать в dict переменных, мне нужен экземпляр подкласса, например. {'x': 1, 'y': 2}

2) возьмите ключи от этого dict и создайте уникальный идентификатор/хэш, например. 34523sdfgsdg3423234234

3) получить этот подкласс из Something.registry, если этот идентификатор существует, и создать экземпляр из этого ИЛИ создать новый подкласс, сохранить его в реестре и вернуть экземпляр его, например. Something.registry будет выглядеть так: {'34523sdfgsdg3423234234':}

Основная отличительная особенность многих подклассифицированных элементов - это информация, которую они несут, и все они делают разные вещи с информацией, которую они носят по-разному, на основе другой информации, которую они несут , но все они являются общими для метода в классе, из которого они подклассифицированы, поэтому я просто пытаюсь создать ключ на основе полезной информации, поэтому я могу начать работать над большей генерацией, которая удаляет избыточный код, и я предполагаю, что я Я кое-что придумаю.

+0

Реестр является в 'Something .__ dict__', а не' SomethingMeta .__ dict__'.Его можно поместить в «SomethingMeta», если хотите, но это не тот момент, когда он находится на данный момент, учитывая текущий код. – unutbu

+0

Можете ли вы привести пример того, как вы хотите, чтобы реестр выглядел (включая список атрибутов)? – unutbu

ответ

0

Код в SomethingMeta.__init__ выполняется в то время, когда определен класс Something (или любой из его подклассов).

Атрибуты экземпляра Something определены только в том случае, если экземпляр создан, что может произойти намного позже или даже никогда.

Поэтому реестр не может проверить экземпляры, чтобы узнать, какие атрибуты он может иметь.

Но если вы можете гарантировать, что атрибуты являются все перечисленные в вызове подписи cls.__init__, то вы можете использовать inspect.getargspec, чтобы найти имена атрибутов:

import inspect 
class SomethingMeta(type): 
    def __init__(cls, name, bases, dct): 
     if not hasattr(cls, 'registry'): 
      cls.registry = {} 
     else: 
      interface_id = name.lower() 
      attrs, varargs, varkw, defaults = inspect.getargspec(cls.__init__) 
      cls.registry[interface_id] = [a for a in attrs 
              if a not in ('self', None)] 

     super(SomethingMeta, cls).__init__(name, bases, dct) 

class Something(object): 
    __metaclass__ = SomethingMeta 

class SomethingA(Something): 
    def __init__(self, x, y, *args, **kw): 
     self.x = x 
     self.y = y 

class SomethingB(Something): 
    def __init__(self, z=0): 
     self.z = z 

print(Something.registry) 

Урожайность

{'somethingb': ['z'], 'somethinga': ['x', 'y']} 
+0

inspect.getargspec - это то, о чем я не знал, и получил немного больше, как ответ на мой первоначальный вопрос. – blueblank