我想编写一个程序,接受一个数字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的做法是什么,我理解会使用元类。
答案 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