Запуск функции словаря с / без аргументов - Python [duplicate]

В то время как , что вызывает NullReferenceExceptions и подходит к avoid / fix , такое исключение было рассмотрено в других ответах, что многие программисты не имеют " t узнал еще, как независимо отлаживать такие исключения во время разработки.

В Visual Studio это обычно легко благодаря Visual Studio Debugger .


Во-первых, убедитесь, что правильная ошибка будет обнаружена - см. . Как разрешить нарушение «Исключение System.NullReferenceException» в VS2010? Примечание1

Затем либо Начать с отладки (F5) , либо Приложить [отладчик VS] к запуску процесса . Иногда может быть полезно использовать Debugger.Break , в котором будет предложено запустить отладчик.

Теперь, когда NullReferenceException выбрано (или необработанно), отладчик остановится ( помните правило, указанное выше?) в строке, на которой произошло исключение. Иногда ошибка может быть легко обнаружена.

Например, в следующей строке единственный код, который может , вызывает исключение, если myString имеет значение null. Это можно проверить, посмотрев окно Watch или выполнив выражения в окне Immediate Window .

var x = myString.Trim();

В более сложных случаях, таких как следуя ниже, вам нужно будет использовать один из методов выше (Watch или Immediate Windows) для проверки выражений, чтобы определить, было ли str1 пустым или если str2 имеет значение null.

var x = str1.Trim() + str2.Trim();

Once , где было выбрано исключение, это обычно тривиально по отношению к разуму назад, чтобы выяснить, где введенное значение null было [неправильно] -

. Найдите время, необходимое для понимания причина исключения. Проверьте нулевые выражения. Проверьте предыдущие выражения, которые могли бы привести к таким нулевым выражениям. Добавьте контрольные точки и, по мере необходимости, пройдите через программу. Используйте отладчик.


1 Если Break on Throws слишком агрессивен и отладчик останавливается на NPE в библиотеке .NET или сторонних разработчиков, Break на User-Unhandled можно использовать для ограничения выловленных исключений. Кроме того, VS2012 представляет Just My Code , который я рекомендую также включить.

Если вы отлаживаете с включенным Just My Code, поведение немного отличается. При включенном Just My Code отладчик игнорирует исключения, связанные с привилегиями обычного языка (CLR) первого шанса, которые выходят за пределы My Code и не проходят через My Code

112
задан Aaron Digulla 11 May 2009 в 14:11
поделиться

5 ответов

Ранее принятый ответ был устаревшим с Python 3.0. Вместо использования inspect.getargspec вы должны выбрать класс Signature, который заменит его.

Создание подписи для функции выполняется с помощью функции signature :

from inspect import signature

def someMethod(self, arg1, kwarg1=None):
    pass

sig = signature(someMethod)

Теперь вы можете быстро просмотреть ее параметры с помощью str:

str(sig)  # returns: '(self, arg1, kwarg1=None)'

или вы также можете получить сопоставление имен атрибутов с объектами параметров через sig.parameters.

params = sig.parameters 
print(params['kwarg1']) # prints: kwarg1=20

Кроме того, вы можете вызвать len на sig.parameters, чтобы увидеть количество аргументов, которые эта функция требует:

print(len(params))  # 3

Каждая запись в params На самом деле отображение - это объект Parameter , который имеет дополнительные атрибуты, облегчающие вашу жизнь. Например, захват параметра и просмотр его значения по умолчанию теперь легко выполняется с помощью:

kwarg1 = params['kwarg1']
kwarg1.default # returns: None

аналогично для остальных объектов, содержащихся в parameters.


Что касается пользователей Python 2.x, в то время как inspect.getargspec не устарел , язык скоро будет :-). Класс Signature недоступен в серии 2.x и не будет. Поэтому вам еще нужно работать с inspect.getargspec .

Что касается перехода между Python 2 и 3, если у вас есть код, который полагается на интерфейс getargspec в Python 2 и переключиться на signature в 3 слишком сложно, у вас есть ценная опция использования inspect.getfullargspec . Он предлагает аналогичный интерфейс getargspec (один вызываемый аргумент), чтобы захватить аргументы функции, а также обрабатывать некоторые дополнительные случаи, которые getargspec не выполняет:

from inspect import getfullargspec

def someMethod(self, arg1, kwarg1=None):
    pass

args = getfullargspec(someMethod)

Как и в случае с getargspec, getfullargspec возвращает NamedTuple, который содержит аргументы.

print(args)
FullArgSpec(args=['self', 'arg1', 'kwarg1'], varargs=None, varkw=None, defaults=(None,), kwonlyargs=[], kwonlydefaults=None, annotations={})
59
ответ дан Jim Fasarakis Hilliard 31 August 2018 в 16:26
поделиться
  • 1
    Добро пожаловать @ GeorgSchölly. Я был удивлен популярным вопросом, подобным этому, который предлагал решения, которые либо были устаревшими, либо проворными (подглядывая в атрибуте co_argcount). – Jim Fasarakis Hilliard 16 December 2016 в 17:37
  • 2
    getfullargspec не реализован в Python 2.x, вам нужно использовать getargspec – Peter Gibson 3 May 2017 в 22:59
  • 3
    getargspec не работает во встроенных функциях: getargspec(open) дает TypeError: <built-in function open> is not a Python function См. этот ответ для некоторых идей ... – starfry 8 May 2017 в 09:50
  • 4
    В последнем примере, когда вы делаете print(args), вы не получаете defaults=(None,), вы получаете defaults=None. – Seanny123 4 July 2018 в 16:42

Как показывают другие ответы, getargspec работает хорошо, пока запрашиваемая вещь на самом деле является функцией. Он не работает для встроенных функций , таких как open, len и т. Д., И генерирует исключение в таких случаях:

TypeError: <built-in function open> is not a Python function

(вдохновленный этим ответом ) демонстрирует обходное решение. Он возвращает число аргументов, ожидаемых f:

from inspect import isfunction, getargspec
def num_args(f):
  if isfunction(f):
    return len(getargspec(f).args)
  else:
    spec = f.__doc__.split('\n')[0]
    args = spec[spec.find('(')+1:spec.find(')')]
    return args.count(',')+1 if args else 0

Идея состоит в том, чтобы проанализировать спецификацию функции из строки __doc__. Очевидно, что это зависит от формата указанной строки, поэтому вряд ли будет надежным!

16
ответ дан Community 31 August 2018 в 16:26
поделиться
import inspect
inspect.getargspec(someMethod)

см. модуль проверки

116
ответ дан Jochen Ritzel 31 August 2018 в 16:26
поделиться
someMethod.func_code.co_argcount

или, если текущее имя функции не определено:

import sys

sys._getframe().func_code.co_argcount
26
ответ дан miaoever 31 August 2018 в 16:26
поделиться
  • 1
    +1, откуда у вас это получилось? – elyase 25 August 2013 в 02:27
  • 2
    @elyase, просто выполните: dir(someMethod) - & gt; 'func_code'; Идем дальше: dir(someMethod.func_code) - & gt; 'co_argcount'; Вы можете использовать встроенный dir() для определения доступных методов объекта. – user 4 February 2014 в 10:00
  • 3
    @elyase Я тоже был зол, поэтому нашел docs.python.org/2/library/inspect.html#types-and-members – rodripf 13 September 2015 в 21:12
  • 4
    Для поддержки Python 3: six.get_function_code(someMethod).co_argcount – noisecapella 8 February 2016 в 20:25
  • 5
    @noisecapella нет необходимости в стороннем модуле, когда вы можете просто сделать some_method.__code__.co_argcount – Vallentin 30 March 2016 в 19:15

Добавляя к вышесказанному, я также видел, что большая часть времени help () действительно помогает

. Например, он дает всю информацию о необходимых аргументах.

help(<method>)

дает ниже

method(self, **kwargs) method of apiclient.discovery.Resource instance
Retrieves a report which is a collection of properties / statistics for a specific customer.

Args:
  date: string, Represents the date in yyyy-mm-dd format for which the data is to be fetched. (required)
  pageToken: string, Token to specify next page.
  parameters: string, Represents the application name, parameter name pairs to fetch in csv as app_name1:param_name1, app_name2:param_name2.

Returns:
  An object of the form:

    { # JSON template for a collection of usage reports.
    "nextPageToken": "A String", # Token for retrieving the next page
    "kind": "admin#reports#usageReports", # Th
3
ответ дан Venu Murthy 31 August 2018 в 16:26
поделиться
  • 1
    Было бы хорошо, если бы люди оставили комментарий о том, что не так с поста, а просто нажмите кнопку «минус». – Venu Murthy 24 December 2013 в 09:40
  • 2
    Функция help показывает только то, что говорит докшрин. Вы даже протестировали, если он работает с определением функции в вопросе? – 0xc0de 2 November 2014 в 18:35
  • 3
    @ 0xc0de - Вы протестировали его? Потому что это действительно работает. help() выплескивает больше, чем только docstring - даже в недокументированном коде он все еще печатает аргумент argspec и сообщает вам, где был определен код. Человек, который отправил оригинальный вопрос, не был ясен, нужен ли им ответ, который был дружественным к машине или человеку. Если это нужно только для человека, help() вполне адекватно. – ArtOfWarfare 18 January 2016 в 00:09
  • 4
    @ArtOfWarfare совсем нет, так как теперь вам нужно будет разобрать все, что help() вернется, и попробуйте найти args и kwargs. – Vallentin 30 March 2016 в 19:18
Другие вопросы по тегам:

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