1

只是按照我发现的一个示例中的某些内容与项目的一部分进行集成,在该项目中,我正在创建大量从下面的“某事”中子类化的类,并且我正在尝试采取步骤以更自动地创建这些项目而无需每次都写出来(因为项目的数量越来越大,我可以通过传入一个较小的属性列表来减少很多样板文件,至少这是要点)。

无论如何,给定:

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中有一个使用'Something'创建的类的注册表......但我真正想做的是在'SomethingMeta'中获取'Something'子类的属性列表。所以在Something.registry中需要捕获一个注册子类的属性,甚至是特定的,即我需要知道当SomethingB被注册时,它上面有一个SomethingB.z,所以我可以获得一个指纹在字典中键入的子类。只有我现在似乎无法正确地戳戳我需要的东西。

任何输入表示赞赏,可以提供澄清,如果我做错了,可能会告诉我到底想做什么,等等。

编辑:

求结果。总的来说,我想:

1)传入我需要子类实例具有的变量的字典,例如 {'x': 1, 'y': 2}

2) 从此字典中获取密钥,并创建一个唯一标识符/哈希,例如 34523sdfgsdg3423234234

3)如果该标识符存在,则从 Something.registry 获取该子类,并从中实例化一个实例或创建一个新子类,将其存储在注册表中并返回它的实例,例如 Something.registry 看起来像 {'34523sdfgsdg3423234234': }

许多子类项目的主要区别特征是它们携带的信息,并且它们都根据它们携带的其他信息以不同的方式使用它们携带的信息做不同的事情,但对于它们子类中的类中的方法都是通用的,所以我真的只是想根据信息有效负载创建一个密钥,这样我就可以开始进行更多的自动生成来删除冗余代码,我想我会想办法的。

4

1 回答 1

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']}
于 2013-03-28T17:07:17.600 回答