아래에 정의 된 Python 함수가 있다고 가정하십시오.
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
를 사용하여 함수의 이름을 얻을 수 있습니다 foo.func_name
. 위에서 입력 한대로 프로그래밍 방식으로 소스 코드를 얻는 방법은 무엇입니까?
foo.__name__
아래에 정의 된 Python 함수가 있다고 가정하십시오.
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
를 사용하여 함수의 이름을 얻을 수 있습니다 foo.func_name
. 위에서 입력 한대로 프로그래밍 방식으로 소스 코드를 얻는 방법은 무엇입니까?
foo.__name__
답변:
함수가 파일 시스템에서 사용 가능한 소스 파일에서 온 것이라면 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
그러나 함수가 문자열에서 컴파일되거나 스트림 또는 컴파일 된 파일에서 가져온 경우 소스 코드를 검색 할 수 없다고 생각합니다.
len
. len
함수 의 소스 코드는 어디에서 찾을 수 있습니까 ?
inspect.getsourcelines(foo)
는 모듈 검사 파이썬 객체의 소스 코드를 검색하는 방법이있다. 소스가 파일에있는 경우에만 작동합니다. 당신이 가지고 있다면 객체에서 소스를 얻을 필요가 없다고 생각합니다.
python 3.5.3
통역사 에서 inspect를 사용해 보았습니다 . import inspect
+ inspect.getsource(foo)
잘 작동했습니다.
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
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/<ipython-input-18-3174e3126506>
Type: function
dir(MyClass)
, 다음 MyClass.__init__??
등등.
나는 그것이 inspect
좋은 대답 이라고 일반적으로 동의하지만 통역사에 정의 된 객체의 소스 코드를 얻을 수 없다는 것에 동의하지 않습니다. dill.source.getsource
from 을 사용 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
>>>
dill.source.getsource
함수, 클래스, 람다 등의 인터프리터 히스토리를 검사합니다. exec에 전달 된 문자열의 내용은 검사하지 않습니다.
dill
이 질문에 대답하는 데 사용할 수 있습니까 : stackoverflow.com/questions/13827543/…
dill.source
기능을 가지고 있습니다 . 소스 가 없는 간단한 것들의 경우 예상대로 작동하지 않습니다 (예 : 'a = 10'의 경우 '10'을 반환합니다). getname
importable
getsource
int
>>> a = 10; print( [key for key, val in globals().items() if val is a][0] )
dill
했지만 내 대답은 약간의 희망을 남깁니다. 이름과 같은 이름으로 평가되는 표현식을 전달하면 대신 해당 이름을 부여합니다.) dill
내 대답의 단점을 해결할 수 있습니다. 여기 : stackoverflow.com/a/28634996/901641
runeh의 답변을 확장하려면 :
>>> 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
. 그러나 소스 파일에서 코드를 가져올 때는 두 가지 모두에 적합합니다.
getsource(foo)
.
inspect
모듈을 사용 하여 전체 소스 코드를 얻을 수 있습니다 . 모듈 getsource()
에서 그 방법 을 사용해야 inspect
합니다. 예를 들면 다음과 같습니다.
import inspect
def get_my_code():
x = "abcd"
return x
print(inspect.getsource(get_my_code))
아래 링크에서 더 많은 옵션을 확인할 수 있습니다. 파이썬 코드를 검색
이 게시물은 이 다른 게시물 의 복제본으로 표시되어 있기 때문에 OP는 람다가 아니지만 "lambda"사례에 대해 여기에 대답합니다.
따라서 자체 줄에 정의되어 있지 않은 람다 함수의 경우 : 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
전체 줄을 제공합니다.
예를 들어 파일을 고려하십시오 test.py
.
import inspect
def main():
x, f = 3, lambda a: a + 1
print(inspect.getsource(f))
if __name__ == "__main__":
main()
그것을 실행하면 (indention을 명심하십시오!)
x, f = 3, lambda a: a + 1
람다의 소스 코드를 검색하려면 가장 좋은 방법은 전체 소스 파일을 다시 구문 분석하고 (을 사용하여 f.__code__.co_filename
) 람다 AST 노드를 줄 번호와 컨텍스트로 일치시키는 것입니다.
우리는 설계자 별 라이브러리 icontract 에서 우리가 데코레이터에게 인수로 전달하는 람다 함수를 구문 분석해야 했기 때문에 정확하게 수행 해야했습니다. 여기에 붙여 넣기에는 너무 많은 코드가 있으므로이 함수의 구현을 살펴보십시오 .
함수를 직접 정의하고 비교적 짧은 정의 인 경우 종속성이없는 해결책은 문자열에서 함수를 정의하고 표현식의 eval ()을 함수에 할당하는 것입니다.
예 :
funcstring = 'lambda x: x> 5'
func = eval(funcstring)
그런 다음 선택적으로 원래 코드를 함수에 첨부하십시오.
func.source = funcstring