什么是“元类”方法呢?

时间:2014-03-06 21:31:01

标签: python metaclass

我想编写一个程序,接受一个数字p作为输入,并为一个服从整数算术模p的数字生成一个类型构造函数。

到目前为止我已经

def IntegersModP(p):
   N = type('IntegersMod%d' % p, (), {})

   def __init__(self, x): self.val = x % p
   def __add__(a, b): return N(a.val + b.val)
   ... (more functions) ...    

   attrs = {'__init__': __init__, '__add__': __add__, ... }

   for name, f in attrs.items():
      setattr(N, name, f)

   return N

这很好用,但我想知道Pythonic的做法是什么,我理解会使用元类。

2 个答案:

答案 0 :(得分:2)

像这样:

def IntegerModP(p):  # class factory function
    class IntegerModP(object):
        def __init__(self, x):
            self.val = x % p
        def __add__(a, b):
            return IntegerModP(a.val + b.val)
        def __str__(self):
            return str(self.val)
        def __repr__(self):
            return '{}({})'.format(self.__class__.__name__, self.val)

    IntegerModP.__name__ = 'IntegerMod%s' % p  # rename created class
    return IntegerModP

IntegerMod4 = IntegerModP(4)
i = IntegerMod4(3)
j = IntegerMod4(2)
print i + j        # 1
print repr(i + j)  # IntegerMod4(1)

答案 1 :(得分:1)

当您的类需要与普通类的行为不同或者您想要更改class语句的行为时,元数据适用。这些都不适用于此,因此实际上不需要使用元类。实际上,你可以只有一个ModularInteger类,其中包含记录其值和模数的实例,但假设你不想这样做,那么使用普通的类语句仍然很容易做到这一点:

def integers_mod_p(p):
    class IntegerModP(object):
        def __init__(self, n):
            self.n = n % IntegerModP.p
        def typecheck(self, other):
            try:
                if self.p != other.p:
                    raise TypeError
            except AttributeError:
                raise TypeError
        def __add__(self, other):
            self.typecheck(other)
            return IntegerModP(self.n + other.n)
        def __sub__(self, other):
            ...
    IntegerModP.p = p
    IntegerModP.__name__ = 'IntegerMod{}'.format(p)
    return IntegerModP