다른 스크립트에서 스크립트를 호출하는 가장 좋은 방법은 무엇입니까?


307

모듈에없는 test1.py라는 스크립트가 있습니다. 스크립트 자체가 실행될 때 실행할 코드 만 있습니다. 함수, 클래스, 메소드 등이 없습니다. 서비스로 실행되는 다른 스크립트가 있습니다. 서비스로 실행되는 스크립트에서 test1.py를 호출하고 싶습니다.

예를 들면 다음과 같습니다.

파일 test1.py

print "I am a test"
print "see! I do nothing productive."

파일 service.py

# Lots of stuff here
test1.py # do whatever is in test1.py

파일을 열고 내용을 읽고 기본적으로 평가하는 방법 중 하나를 알고 있습니다. 더 좋은 방법이 있다고 가정합니다. 아니면 적어도 그렇게 희망합니다.


42
더 좋은 방법은 메소드와 클래스를 작성하고 사용하는 것입니다.
Aamir


3
runpy.run_module아직 답변을 게시 한 사람이 없습니까 ?!
Aran-Fey

답변:


279

이를 수행하는 일반적인 방법은 다음과 같습니다.

test1.py

def some_func():
    print 'in test 1, unproductive'

if __name__ == '__main__':
    # test1.py executed as script
    # do something
    some_func()

service.py

import test1

def service_func():
    print 'service func'

if __name__ == '__main__':
    # service.py executed as script
    # do something
    service_func()
    test1.some_func()

44
test1.py멀리 떨어진 디렉토리에 있으면 어떻게 합니까?
Evgeni Sergeev 2016 년


18
그래도 실제로 질문에 대답하지는 않습니까? 전체 스크립트를 실행하지 않고 가져온 스크립트 내에서 일부 기능을 실행하고 있습니다.
10

2
@GennaroTedesco : 당신은 착각입니다. import test1에서이 service.py실제로 실행 않습니다 전체 (만 정의 스크립트 some_func()이후 __name__ == '__main__'가 될 것이다 False이 경우 참조). 모든 OP가 원하는 것처럼 들립니다. 이 답변은 그 이상이지만, 그 질문에 대한 대답은 물론 일부는 확실하게 대답합니다.
martineau

2
예를 test1.py들어 함수의 정의를 포함하지 않은 경우 some_func()(예를 들어 일부 코드 줄 print("hello")) 코드가 작동하지 않습니다. 이 특정 예제에서는 나중에 호출하는 외부 함수를 본질적으로 가져 오기 때문에 작동합니다.

144

이것은 파이썬 2에서 사용할 수 있습니다

execfile("test2.py")

중요한 경우 네임 스페이스 처리에 대한 설명서 를 참조하십시오 .

파이썬 3에서는 (@fantastory 덕분에)

exec(open("test2.py").read())

그러나 다른 접근 방식을 고려해야합니다. 당신의 아이디어 (내가 볼 수있는 것)는 매우 깨끗하게 보이지 않습니다.


9
파이썬 32에서 직접 필요한 것은 exec (open ( 'test2.py'). read ())
fantastory

8
이 방법은 호출 네임 스페이스 내에서 스크립트를 실행합니다. :)
dmvianna

6
스크립트에 명령 행 인수를 전달하기 위해 sys.argv목록을 편집 할 수 있습니다.
jfs

1
Python 3에 대한보다 포괄적 인 처리 : stackoverflow.com/questions/436198/…
John Y

2
이것은 인수를 허용하지 않습니다 (PY 파일로 전달됨)!
Apostolos

70

또 다른 방법:

파일 test1.py :

print "test1.py"

파일 service.py :

import subprocess

subprocess.call("test1.py", shell=True)

이 방법의 장점은 모든 코드를 서브 루틴에 넣기 위해 기존 Python 스크립트를 편집 할 필요가 없다는 것입니다.

문서 : Python 2 , Python 3


7
나는 subprocess.call("./test1.py", shell=True)그것을 작동시키기 위해 사용해야 했다
asmaier

5
필요하지 않으면 사용 shell=True하지 마십시오 .
Piotr Dobrogost

2
@PiotrDobrogost-필요한 상황을 지정할 수 있습니까?
sancho.s ReinstateMonicaCellio

7
현재 디렉토리가 PATH에없는 일반적인 Unix에서는 작동하지 않습니다. test1.py실행 가능하고, 오두막 라인을 (해야 #!/usr/bin/env python)과 전체 경로를 지정해야하거나 실행 직접 제공해야합니다 : 여기에 정의됩니다 . call([sys.executable, os.path.join(get_script_dir(), 'test1.py')])get_script_dir()
jfs

5
또는 subprocess.call(['python', 'test1.py']).
Big McLargeHuge

21

test1.py가 service.py 내부에서 호출 될 때와 동일한 기능으로 실행 가능하게하려면 다음과 같이하십시오.

test1.py

def main():
    print "I am a test"
    print "see! I do nothing productive."

if __name__ == "__main__":
    main()

service.py

import test1
# lots of stuff here
test1.main() # do whatever is in test1.py

3
런타임 매개 변수가 있으면 어떻게합니까?
Gabriel Fair

13
import os

os.system("python myOtherScript.py arg1 arg2 arg3")  

os를 사용하면 터미널로 직접 전화를 걸 수 있습니다. 더 구체적으로 만들고 싶다면 입력 문자열을 로컬 변수와 연결할 수 있습니다.

command = 'python myOtherScript.py ' + sys.argv[1] + ' ' + sys.argv[2]
os.system(command)

전화를 os.system피해야합니다.Popen, Call,
user1767754

로부터 파이썬 문서 : 서브 프로세스 모듈은 새로운 프로세스를 산란하고 결과를 검색하기위한보다 강력한 기능을 제공합니다; 이 기능을 사용하는 것보다 해당 모듈을 사용하는 것이 좋습니다.
Big McLargeHuge

12

이러면 안됩니다. 대신 다음을 수행하십시오.

test1.py :

 def print_test():
      print "I am a test"
      print "see! I do nothing productive."

service.py

#near the top
from test1 import print_test
#lots of stuff here
print_test()

1
test1을 가져올 때 파일이 어디에 있는지 어떻게 알 수 있습니까? 동일한 디렉토리에 있어야합니까? 그렇지 않은 경우 어떻게해야합니까?
NULL.Dude

8

사용 import test11 사용을위한 -이 스크립트를 실행합니다. 나중에 호출하려면 스크립트를 가져온 모듈로 취급하고 reload(test1)메소드를 호출하십시오 .

reload(module)실행될 때 :

  • 파이썬 모듈의 코드가 다시 컴파일되고 모듈 수준 코드가 다시 실행 되어 모듈 사전의 이름에 바인딩되는 새로운 객체 집합을 정의합니다. 확장 모듈의 초기화 기능이 호출되지 않습니다

sys.modules적절한 조치를 호출하기 위해 간단한 점검을 사용할 수 있습니다. 스크립트 이름을 문자열 ( 'test1') 로 계속 언급하려면 ' import ()' 내장을 사용하십시오.

import sys
if sys.modules.has_key['test1']:
    reload(sys.modules['test1'])
else:
    __import__('test1')

3
reload파이썬 3에서 사라졌습니다.
Piotr Dobrogost

1
모듈을 가져 오는 것은 해당 모듈을 실행하는 것과 if __name__ == "__main__":다릅니다. 다른 미묘한 차이가있을 수 있습니다. 임의의 코드를 전역 수준에 두지 마십시오. 함수에 넣어와에 제안 가져 오기 후 전화를 허용 대답 대신에
JFS

5

나는 콧물을 선호한다 :

#!/usr/bin/env python
# coding: utf-8

import runpy

runpy.run_path(path_name='script-01.py')
runpy.run_path(path_name='script-02.py')
runpy.run_path(path_name='script-03.py')

3

왜 test1을 가져 오지 않습니까? 모든 파이썬 스크립트는 모듈입니다. 더 좋은 방법은 test1.py에서 main / run, test1을 가져오고 test1.main ()을 실행하는 것입니다. 또는 test1.py를 하위 프로세스로 실행할 수 있습니다.


3

이미 언급했듯이 runpy현재 스크립트에서 다른 스크립트 또는 모듈을 실행하는 좋은 방법입니다.

그건 그렇고, 추적 프로그램이나 디버거 가이 작업을 수행하는 것이 일반적이며 파일을 직접 가져 오거나 하위 프로세스에서 파일을 실행하는 것과 같은 방법은 일반적으로 작동하지 않습니다.

또한 exec코드를 실행하는 데 주의를 기울여야합니다 . run_globals가져 오기 오류나 다른 문제를 피하려면 적절한 정보를 제공해야 합니다. 자세한 runpy._run_code내용은 참조하십시오.


0

이것은 subprocess라이브러리 의 예입니다 .

import subprocess

python_version = '3'
path_to_run = './'
py_name = '__main__.py'

# args = [f"python{python_version}", f"{path_to_run}{py_name}"]  # Avaible in python3
args = ["python{}".format(python_version), "{}{}".format(path_to_run, py_name)]

res = subprocess.Popen(args, stdout=subprocess.PIPE)
output, error_ = res.communicate()

if not error_:
    print(output)
else:
    print(error_)

1
Python의 하위 프로세스로 Python을 실행하는 것은 올바른 솔루션이 아닙니다. 하위 프로세스를 수행하는 Popen경우 상위 수준 함수가 실제로 원하는 작업을 수행 할 수없는 경우가 아니면 피해야 합니다. 이 경우, check_call또는 run자신의 코드에 실질적으로 적은 배관으로, 더 당신이 필요로하는 모든 일을하고있다.
tripleee

0

이 과정은 다소 정통적이지 않지만 모든 파이썬 버전에서 작동합니다.

'if'조건 내에서 'recommend.py'라는 스크립트를 실행하고 다음을 사용한다고 가정합니다.

if condition:
       import recommend

기술은 다르지만 작동합니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.