课程定义后自动做一些事情?

时间:2013-06-13 06:45:14

标签: python-3.x metaprogramming

我想要的是以下内容:

lst = []

class Awesome:
  """This is my magical super class."""

  ...

class Inherits(Awesome):
  """Awesome does awesome stuff with Inherits."""
  name = "Stack"

class InheritsAgain(Awesome):
  name = "Overflow"

print(lst)
#: ['Stack', 'Overflow']

所以基本上,当定义类InheritsInheritsAgain时,因为它们 继承自AwesomeAwesome有一些元类魔法(或其他),即读取 继承类中的属性name,并将其附加到lst

我看过Python中的元类,但我不确定它是如何组合在一起的。

这在Python中可行吗?如果是的话,你会怎么做呢?

修改

让我们添加上面的例子,这样也可以:

class AndAgain(Awesome):
  name = "/root/path/<name>/<id>"

  def go():
    pass

我希望定义整个班级AndAgain,以便我可以检查name是否存在值"/root/path/<name>/<id>",而函数go()也存在

2 个答案:

答案 0 :(得分:2)

lst = []

class AwesomeMeta(type):
    def __new__(metacls, cls, bases, classdict):
        if cls != 'Awesome':
            lst.append(cls)
        return super().__new__(metacls, cls, bases, classdict)

class Awesome(metaclass=AwesomeMeta):
  """This is my magical super class."""


class Stack(Awesome):
  """Awesome does awesome stuff with Inherits."""


class Overflow(Awesome):
    """More awesomely stuff!"""

print(lst)

要在课堂上展示:

lst = []

class AwesomeMeta(type):
    def __new__(metacls, cls, bases, classdict):
        if 'name' in classdict:
            lst.append(classdict['name'])
        return super().__new__(metacls, cls, bases, classdict)

class Awesome(metaclass=AwesomeMeta):
    """This is my magical super class."""


class Inherits(Awesome):
    """Awesome does awesome stuff with Inherits."""

    name = 'Stack'


class InheritsAgain(Awesome):
    """More awesomely stuff!"""

    name = 'Overflow'

class AndAgain(Awesome):
    name = "/root/path/<name>/<id>"

    def go():
        pass

print(lst)

答案 1 :(得分:1)

可以使用元类

class AwesomeMeta(type):
    lst = []
    def __new__(metacls, cls, bases, classdict):
        if 'name' in classdict:
            metacls.lst.append(classdict['name'])
        return super(AwesomeMeta, metacls).__new__(metacls, cls, bases, classdict)

class Awesome(object):
    """This is my magical super class."""
    __metaclass__ = AwesomeMeta


class Inherits(Awesome):
    """Awesome does awesome stuff with Inherits."""
    name = 'Stack'


class InheritsAgain(Awesome):
    """More awesomely stuff!"""
    name = 'Overflow'

print InheritsAgain.lst, Inherits.lst, Awesome.lst

或者可以使用__subclasses__方法

print [i.name for i in Awesome.__subclasses__()]

或者可以使用类装饰器

lst = []
def cls_decorator(cls):
    lst.append(cls.name)
    return cls

@cls_decorator
class Awesome(object):
    """This is my magical super class."""
    name = 'Awesome'


@cls_decorator
class Inherits(Awesome):
    """Awesome does awesome stuff with Inherits."""
    name = 'Stack'


@cls_decorator
class InheritsAgain(Awesome):
    """More awesomely stuff!"""
    name = 'Overflow'

解决方案应该取决于你打算做什么