我正在尝试编写一个程序来执行算术mod n,给定n。我想知道在Python(最好是2.7)中是否有任何方法可以动态定义一个函数,使其行为取决于用于调用它的名称。更具体地说,我想定义一个名为“* mod”的函数,其中*是一个整数,然后算术运算mod *。也许更清楚的是,我想为* mod编写一个函数定义,定义函数2mod,3mod,4mod等。这可能吗?如果已经提出过类似的问题或者我的答案是否可以在文档中找到,我会道歉;我试图搜索它,但我不知道如何描述我正在寻找的功能,所以我可能错过了它。
谢谢!
答案 0 :(得分:4)
你不想这样做。只需创建一个简单的函数并将两个数字作为参数传递:
def mod(x, n):
return x % n
print mod(5, 2)
# 1
答案 1 :(得分:3)
好吧,如果你真的,真的想要,看看这个快速黑客。它uses a wrapper class将模块包装在一个类中,因此您可以使用__getattr__
:
import sys
import functools
def add(a, b):
return a + b
def sub(a, b):
return a - b
class Wrapper(object):
def __init__(self, wrapped):
self.wrapped = wrapped
def __getattr__(self, name):
try:
# quick hack. Don't try this at home :-)
f = ''.join(x for x in name if not x.isdigit())
n = ''.join(x for x in name if x.isdigit())
return functools.partial(getattr(self.wrapped, f), int(n))
except:
return getattr(self.wrapped, name)
sys.modules[__name__] = Wrapper(sys.modules[__name__])
现在,当你打电话时,此模块上的add10(12)
,结果为22.请注意,方法名称不能以数字开头,但您可以使用_add
之类的名称,并调用_55add(45)
等方法。
但我会关注Haidro advice:您不想这样做。只用两个参数调用方法就简单多了。
答案 2 :(得分:1)
使用globals,lambda:
for i in range(2, 5):
globals()['mod{}'.format(i)] = lambda x, n=i: x % n
assert mod2(4) == 0
assert mod2(3) == 1
assert mod3(2) == 2
assert mod3(1) == 1
assert mod4(1) == 1
assert mod4(2) == 2
assert mod4(3) == 3
assert mod4(9) == 1
答案 3 :(得分:0)
您可以通过将函数生成为字符串来实现此目的,然后使用exec
此字符串来获取当前命名空间中的函数。类似的东西:
n = 2
s = 'def mod%i(x):' % n
s += ' return x %% %i' % n
exec s
这将定义函数mod2(x)