Python 함수의 소스코드는 어떻게 얻을 수 있나요?
아래에 정의된 Python 함수가 있다고 가정합니다.
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
은 '하다'를 사용해서 알 수.foo.func_name위에서 입력한 것과 같이 소스코드를 프로그래밍 방식으로 취득하려면 어떻게 해야 합니까?
기능이 파일 시스템에서 사용 가능한 소스 파일에서 가져온 경우 다음과 같이 도움이 될 수 있습니다.
iffoo는 다음과 같습니다
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
그러나 함수가 문자열, 스트림 또는 컴파일된 파일에서 컴파일된 경우 소스 코드를 가져올 수 없다고 생각합니다.
검사 모듈에는 python 개체에서 소스 코드를 검색하는 메서드가 있습니다.다만, 소스가 파일에 있는 경우에만 기능하는 것 같습니다.만약 당신이 그것을 가지고 있다면, 당신은 물체로부터 근원을 얻을 필요가 없을 것입니다.
는 다음과 같습니다.inspect.getsource(foo)Python 3.6 사 :
import inspect
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
source_foo = inspect.getsource(foo) # foo is normal function
print(source_foo)
source_max = inspect.getsource(max) # max is a built-in function
print(source_max)
첫 번째 인쇄:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
하게 됩니다.inspect.getsource(max)하다
TypeError: <built-in function max> is not a module, class, method, function, traceback, frame, or code object
쓰세요.foo?? ★★★★★★★★★★★★★★★★★」??foo.
사용하는 IPython을 .foo?? ★★★★★★★★★★★★★★★★★」??foo전체 소스 코드를 확인합니다.하려면 docstring을 합니다.foo? ★★★★★★★★★★★★★★★★★」?foo주피터
In [19]: foo??
Signature: foo(arg1, arg2)
Source:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
File: ~/Desktop/<ipython-input-18-3174e3126506>
Type: function
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
는 대체로inspect좋은 답변입니다.인터프리터에 정의되어 있는 오브젝트의 소스 코드를 얻을 수 없다는 것에 동의하지 않습니다.「 」를 사용하고 dill.source.getsource에서 함수와 람다의 소스를 얻을 수 있습니다(대화형으로 정의되어 있는 경우라도).또한 curry에 정의된 bound 또는 unbound 클래스 메서드 및 함수에서 코드를 가져올 수 있습니다.그러나 동봉된 객체의 코드가 없으면 해당 코드를 컴파일할 수 없습니다.
>>> 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
>>>
Rune의 답변을 확장하려면:
>>> 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
이 는 EDIT: @0sh를 사용하여 합니다.ipython, 간단하지 않다python그러나 소스 파일에서 코드를 가져올 때는 둘 다 문제가 없습니다.
이 투고는 다른 투고와 중복되어 있기 때문에, OP는 람다에 관한 것이 아니지만, 「람다」의 케이스에 대해서는, 여기에 회답합니다.
따라서 자체 행에 정의되지 않은 람다 함수의 경우: marko.ristin의 응답 외에 mini-lambda 또는 SymPy를 사용할 수 있습니다.
mini-lambda는, 보다 , 종류의을 서포트하고 만, 합니다.SymPy더 무겁지만 수학적/정확한 연산을 훨씬 더 많이 갖추고 있습니다.특히 표현을 단순화할 수 있습니다.또한 동일한 식에서 여러 변수를 지원합니다.
, 이렇게 .mini-lambda:
from mini_lambda import x, is_mini_lambda_expr
import inspect
def get_source_code_str(f):
if is_mini_lambda_expr(f):
return f.to_string()
else:
return inspect.getsource(f)
# test it
def foo(arg1, arg2):
# do something with args
a = arg1 + arg2
return a
print(get_source_code_str(foo))
print(get_source_code_str(x ** 2))
그것은 올바르게 산출된다.
def foo(arg1, arg2):
# do something with args
a = arg1 + arg2
return a
x ** 2
것은, 을 참조하십시오.mini-lambda 자세한 것은, 을 참조하십시오.참고로 저는 작가입니다;)
하시면 됩니다.inspect 수 있습니다. 쓰셔야 돼요.getsource()을 .inspect를 들어 다음과 같습니다예를 들어 다음과 같습니다.
import inspect
def get_my_code():
x = "abcd"
return x
print(inspect.getsource(get_my_code))
아래 링크에서 더 많은 옵션을 확인할 수 있습니다.python 코드 검색
요약:
import inspect
print( "".join(inspect.getsourcelines(foo)[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 lamda AST 。
우리는 디자인 바이 컨트랙트 라이브러리 아이콘트랙트에서 정확히 그것을 해야 했습니다. 왜냐하면 우리는 장식가들에게 논쟁으로 전달되는 람다 함수를 해석해야 했기 때문입니다.여기에 붙이기에는 코드가 너무 많으므로 이 기능의 실장을 확인해 주십시오.
함수 자체를 엄밀하게 정의하고 비교적 짧은 정의일 경우 종속성이 없는 솔루션은 함수를 문자열로 정의하고 식의 eval()을 함수에 할당하는 것입니다.
예.
funcstring = 'lambda x: x> 5'
func = eval(funcstring)
그런 다음 필요에 따라 원래 코드를 함수에 첨부합니다.
func.source = funcstring
Rafau Dowgird의 답변은 다음과 같습니다.
문자열, 스트림 또는 컴파일된 파일에서 함수를 컴파일하면 소스 코드를 가져올 수 없다고 생각합니다.
단, 컴파일된 함수의 소스 코드를 문자열에서 취득할 수 있습니다.단, 컴파일된 코드에는 엔트리가 추가되어 있습니다.linecache.cachedict:
import linecache
import inspect
script = '''
def add_nums(a, b):
return a + b
'''
bytecode = compile(script, 'unique_filename', 'exec')
tmp = {}
eval(bytecode, {}, tmp)
add_nums = tmp["add_nums"]
linecache.cache['unique_filename'] = (
len(script),
None,
script.splitlines(True),
'unique_filename',
)
print(inspect.getsource(add_nums))
# prints:
# """
# def add_nums(a, b):
# return a + b
# """
이것이 클래스가 초기화할 것으로 예상되는 속성 세트를 지정하면 라이브러리가 클래스에 대한 다양한 메서드를 자동으로 만드는 방법입니다.소스코드를 참조해 주세요.소스 설명에 따르면 이는 주로 PDB 등의 디버거가 코드를 통과할 수 있도록 하기 위한 기능입니다.
변수 이름은 pyc/pyd/po 파일에 저장되지 않기 때문에 소스 파일이 없으면 정확한 코드 라인을 검색할 수 없다고 생각합니다.
언급URL : https://stackoverflow.com/questions/427453/how-can-i-get-the-source-code-of-a-python-function
'programing' 카테고리의 다른 글
| MySQL 테이블 업데이트 및 중복 항목 무시 (0) | 2022.12.10 |
|---|---|
| 배열에 요소가 있는지 확인합니다. (0) | 2022.12.10 |
| [ Information Schema COLUNS ]테이블의 컬럼 유형 (0) | 2022.12.10 |
| MySQL: 잘못된 그룹 함수 사용 (0) | 2022.12.10 |
| SQL 구문. 사용하는 올바른 구문은 MariaDB 서버 버전에 해당하는 매뉴얼을 참조하십시오. (0) | 2022.12.10 |