Как я могу получить исходный код функции Python?

Предположим, у меня есть функция Python, как определено ниже:

def foo(arg1,arg2):
    #do something with args
    a = arg1 + arg2
    return a

Я могу получить имя функции, используя foo.func_name. Как я могу программно получить его исходный код, как я напечатал выше?

вопрос задан 9.01.2009
Željko Filipin
37923 репутация

11 ответов


  • 389 рейтинг

    Если функция из исходного файла, доступного в файловой системе, то может помочь inspect.getsource(foo) :

    Если foo определен как:

    def foo(arg1,arg2):         
        #do something with args 
        a = arg1 + arg2         
        return a  
    

    Тогда:

    import inspect
    lines = inspect.getsource(foo)
    print(lines)
    

    Возвращает:

    def foo(arg1,arg2):         
        #do something with args 
        a = arg1 + arg2         
        return a                
    

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

    ответ дан Rafał Dowgird, с репутацией 30422, 9.01.2009
  • 172 рейтинг

    В модуле проверки есть методы для получения исходного кода из объектов Python. По-видимому, это работает только в том случае, если источник находится в файле. Если бы у вас было это, я думаю, вам не нужно было бы получать источник от объекта.

    ответ дан runeh, с репутацией 2886, 9.01.2009
  • 71 рейтинг

    dis ваш друг, если исходный код недоступен:

    >>> import dis
    >>> def foo(arg1,arg2):
    ...     #do something with args
    ...     a = arg1 + arg2
    ...     return a
    ...
    >>> dis.dis(foo)
      3           0 LOAD_FAST                0 (arg1)
                  3 LOAD_FAST                1 (arg2)
                  6 BINARY_ADD
                  7 STORE_FAST               2 (a)
    
      4          10 LOAD_FAST                2 (a)
                 13 RETURN_VALUE
    
    ответ дан schlamar, с репутацией 6460, 28.06.2013
  • 48 рейтинг

    Хотя я в целом согласен с тем, что inspect - хороший ответ, я не согласен с тем, что вы не можете получить исходный код объектов, определенных в интерпретаторе. Если вы используете dill.source.getsource из dill , вы можете получить источник функций и лямбд, даже если они определены интерактивно. Он также может получить код для связанных или несвязанных методов и функций класса, определенных в карри. , , однако, вы не сможете скомпилировать этот код без кода вмещающего объекта.

    >>> from dill.source import getsource
    >>> 
    >>> def add(x,y):
    ...   return x+y
    ... 
    >>> squared = lambda x:x**2
    >>> 
    >>> print getsource(add)
    def add(x,y):
      return x+y
    
    >>> print getsource(squared)
    squared = lambda x:x**2
    
    >>> 
    >>> class Foo(object):
    ...   def bar(self, x):
    ...     return x*x+x
    ... 
    >>> f = Foo()
    >>> 
    >>> print getsource(f.bar)
    def bar(self, x):
        return x*x+x
    
    >>> 
    
    ответ дан Mike McKerns, с репутацией 16345, 24.01.2014
  • 48 рейтинг

    Если вы используете IPython, то вам нужно набрать "foo? ? "

    In [19]: foo??
    Signature: foo(arg1, arg2)
    Source:
    def foo(arg1,arg2):
        #do something with args
        a = arg1 + arg2
        return a
    
    File:      ~/Desktop/
    Type:      function
    
    ответ дан prashanth, с репутацией 1411, 9.05.2016
  • 20 рейтинг

    Расширить ответ Руны:

    >>> def foo(a):
    ...    x = 2
    ...    return x + a
    
    >>> import inspect
    
    >>> inspect.getsource(foo)
    u'def foo(a):\n    x = 2\n    return x + a\n'
    
    print inspect.getsource(foo)
    def foo(a):
       x = 2
       return x + a
    

    РЕДАКТИРОВАТЬ: Как указано @ 0sh, этот пример работает с использованием ipython, но не простой python. Однако при импорте кода из исходных файлов все должно быть хорошо.

    ответ дан TomDotTom, с репутацией 2991, 3.08.2014
  • 10 рейтинг

    Вы можете использовать модуль inspect, чтобы получить полный исходный код для этого. Для этого вы должны использовать метод getsource() из модуля inspect. Например:

    import inspect
    
    def get_my_code():
        x = "abcd"
        return x
    
    print(inspect.getsource(get_my_code))
    

    Вы можете проверить больше вариантов по ссылке ниже. получить код Python

    ответ дан Krutarth Gor, с репутацией 119, 9.07.2017
  • 3 рейтинг

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

    E. г.

    funcstring = 'lambda x: x> 5'
    func = eval(funcstring)
    

    затем при желании присоединить исходный код к функции:

    func.source = funcstring
    
    ответ дан cherplunk, с репутацией 57, 17.04.2012
  • 2 рейтинг

    , чтобы подвести итог:

    import inspect
    print( "".join(inspect.getsourcelines(foo)[0]))
    
    ответ дан douardo, с репутацией 164, 3.01.2017
  • 0 рейтинг

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

    Например, рассмотрим файл test.py:

    import inspect
    
    def main():
        x, f = 3, lambda a: a + 1
        print(inspect.getsource(f))
    
    if __name__ == "__main__":
        main()
    

    Выполнение этого дает вам (помните отступ! ):

        x, f = 3, lambda a: a + 1
    

    Чтобы получить исходный код лямбды, лучше всего, на мой взгляд, повторно проанализировать весь исходный файл (используя f.__code__.co_filename) и сопоставить лямбда-узел AST по номеру строки и ее контексту.

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

    ответ дан marko.ristin, с репутацией 58, 14.09.2018
  • -2 рейтинг

    Я считаю , что имена переменных не хранятся в файлах pyc / pyd / pyo, поэтому вы не можете получить точные строки кода, если у вас нет исходных файлов.

    ответ дан Abgan, с репутацией 2945, 9.01.2009