Это единственный способ, который я могу придумать, который должен быть на 100% эффективным (по крайней мере, в отношении того, определена ли функция пользователем или написана на С) при определении (минимальной) арности функции. Тем не менее, вы должны быть уверены, что эта функция не вызовет никаких побочных эффектов и что она не вызовет ошибку TypeError:
from functools import partial
def arity(func):
pfunc = func
i = 0
while True:
try:
pfunc()
except TypeError:
pfunc = partial(pfunc, '')
i += 1
else:
return i
def foo(x, y, z):
pass
def varfoo(*args):
pass
class klass(object):
def klassfoo(self):
pass
print arity(foo)
print arity(varfoo)
x = klass()
print arity(x.klassfoo)
# output
# 3
# 0
# 0
Как видите, это будет определять минимум арности, если функция принимает переменное количество аргументов. Он также не учитывает аргумент self или cls метода класса или экземпляра.
Честно говоря, я бы не использовал эту функцию в производственной среде, если бы точно не знал, какие функции будут вызываться, поскольку в ней много места для глупых ошибок. Это может победить цель.