Как узнать арность метода в Python

после входа в систему при повторном нажатии звоните moveTaskToBack(true);

из этого ваше приложение будет в фоновом режиме. надеюсь, что поможет

30
задан Federico Builes 13 June 2009 в 15:40
поделиться

5 ответов

Модуль inspect из стандартной библиотеки Python - ваш друг - см. онлайн-документацию ! inspect.getargspec (func) возвращает кортеж с четырьмя элементами, args, varargs, varkw, значениями по умолчанию : len (args) является «первичной арностью», но арность может быть любой, от этой до бесконечности, если у вас есть varargs и / или varkw not None , а некоторые аргументы можно опустить (и использовать по умолчанию), если по умолчанию не Нет . Меня больше не интересует то, как вы превращаете это в одно число, но, по-видимому, у вас есть свои идеи! -)

Это относится к функциям, кодируемым на Python, но не к функциям на языке C. Ничто в Python C API не позволяет кодируемым на C функциям (включая встроенные) раскрывать свою сигнатуру для интроспекции, кроме как через строку документации (или, необязательно, через аннотации в Python 3); так что вам придется вернуться к синтаксическому анализу строки документации в качестве последней черты, если другие подходы потерпят неудачу (конечно, строка документации также может отсутствовать, и в этом случае функция останется загадкой).

48
ответ дан 27 November 2019 в 23:47
поделиться

В идеале, вам нужно обезьяно исправить функцию arity как метод на функторах Python. Вот как:

def arity(self, method):
    return getattr(self.__class__, method).func_code.co_argcount - 1

functor = arity.__class__
functor.arity = arity
arity.__class__.arity = arity

Но CPython реализует функторы в C, вы не можете их изменить. Однако это может работать в PyPy.

Это все, если ваша функция arity () верна. А как насчет вариативных функций? Вы вообще хотите получить ответ?

2
ответ дан 27 November 2019 в 23:47
поделиться

Используйте декоратор для украшения методов, например

def arity(method):

  def _arity():
    return method.func_code.co_argcount - 1 # remove self

  method.arity = _arity

  return method

class Foo:
  @arity
  def bar(self, bla):
    pass

print Foo().bar.arity()

Теперь реализуйте функцию _arity , чтобы вычислить количество аргументов в зависимости от ваших потребностей

6
ответ дан 27 November 2019 в 23:47
поделиться

Это единственный способ, который, как мне кажется, должен быть на 100% эффективным (по крайней мере, в отношении того, является ли функция определяемой пользователем или написанной на C) при определении функции (минимум ) арность. Однако вы должны быть уверены, что эта функция не вызовет никаких побочных эффектов и не вызовет ошибку 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 метода класса или экземпляра.

Если быть полностью честным, я бы не стал использовать эту функцию в производственной среде, если бы не знал точно, какие функции будут вызываться, хотя так как есть много места для глупых ошибок. Это может свести на нет цель.

2
ответ дан 27 November 2019 в 23:47
поделиться

вот еще одна попытка использования метакласса, так как я использую python 2.5, но с 2.6 вы можете легко украсить класс

метакласс также может быть определен на уровне модуля, поэтому он работает для всех классов

from types import FunctionType

def arity(unboundmethod):
    def _arity():
        return unboundmethod.func_code.co_argcount - 1 # remove self
    unboundmethod.arity = _arity

    return unboundmethod

class AirtyMetaclass(type):
    def __new__(meta, name, bases, attrs):
        newAttrs = {}
        for attributeName, attribute in attrs.items():
            if type(attribute) == FunctionType:
                attribute = arity(attribute)

            newAttrs[attributeName] = attribute

        klass = type.__new__(meta, name, bases, newAttrs)

        return klass

class Foo:
    __metaclass__ = AirtyMetaclass
    def bar(self, bla):
        pass

print Foo().bar.arity()
0
ответ дан 27 November 2019 в 23:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: