Python 什么是「;元类;如何做到这一点?
我想写一个程序,它接受一个数字p作为输入,并为一个服从整数算术模p的数字生成一个类型构造函数作为输出 到目前为止我有Python 什么是「;元类;如何做到这一点?,python,metaclass,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) ... att
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
这很好,但我想知道python的方法是什么,我知道它会使用元类。像这样:
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)
元类适用于您的类需要与普通类不同的行为,或者您想要更改
类
语句的行为时。这两种方法都不适用于这里,因此实际上没有必要使用元类。事实上,您可以只使用一个带有实例的ModularInteger
类来记录它们的值和模数,但假设您不想这样做,那么使用普通的class语句仍然很容易做到这一点:
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
我不确定您为什么要在这里使用元类,您可以使用一个简单的class语句并将
p
传递到\uuuuuu init\uuuuu
@AshwiniChaudhary。这是不可接受的,因为您不能添加具有不同模块的两个实例。(您将使用哪个模数?@JeremyKun您可以将模数存储在实例本身中,然后在实际对两个实例执行操作之前检查它们的模数。@AshwiniChaudhary这是一个非常不雅观的解决方案。@JeremyKun:您的答案根本不检查模数。添加两个具有不同模块的数字会产生无意义的结果。您可能希望将p
存储在类中,而不是作为闭包变量,以便于内省,并添加一些类型检查,以便在不同模块中使用数字进行数学运算时不会只给出错误的结果。@user2357112:我只是概述了一个“Pythonic”为OP构造这样一个类的方法并没有实现问题中定义得很模糊的东西——此外,类的最终名称应该足以用于内省。@AshwiniChaudhary:的确如此。我本来打算让它用一个更复杂的类型检查来处理这个问题,但是我分心了,忘记了。我认为我对这个问题不太满意,因为我希望尽可能避免错误(最终我计划使这个类更通用,所以我想在可能的情况下进行一些无声类型转换)。但我想你已经告诉我,我只需要更加认真地思考我想如何组织事情,这是对我前面提到的问题的一个很好的回答。