앞으로    목차    1    2    3    4    5    6    7    제8장    다음으로

8. 윈도우에서의 파이썬

8.1. 마이크로소프트 윈도우에서 파이썬을 CGI로 사용하기

마이크로소프트 IIS 서버/Peer 서버를 설정하기:

마이크로소프트 IIS 서버 또는 Win95 MS 개인 웹 서버에서 다른 스크립트 엔진을 설정하는 것과 마찬가지 방식으로 파이썬을 설정합니다.

regedt32를 실행하시고 다음으로 가세요:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters\ScriptMap

그리고 다음의 라인을 입력하세요 (여러분의 시스템이 필요로 하는 어떤 특정한 변경을 하세요)

.py :REG_SZ: c:\<path to python>\python.exe -u %s %s

이 라인으로 여러분은 스크립트를 간단한 참조로 다음과 같이 호출할 수 있게 됩니다: "스크립트"로 주어진 http://yourserver/scripts/yourscript.py는 여러분의 서버에 대하여 "실행가능" 디렉토리가 됩니다. (보통은 이것이 기본입니다). "-u" 플래그는 표준입력에 대하여 비완충모드 그리고 이진 모드를 지정합니다 - 이진 데이타와 작업할 때 필요합니다

게다가, 이러한 문맥에서 사용될 때 그 파일 확장자를 위하여 ".py"를 사용하는 것은 좋은 생각이 아니라는 것을 아는 사람들은 그것을 권장합니다. (여러분은 *.py를 지원 모듈을 위하여 예약해두고 *.cgi 또는 *.cgp를 "주 프로그램" 스크립트를 사용하고 싶을 수도 있습니다). 그렇지만, 그 문제는 이 윈도우 FAQ 항목을 벗어나는 것입니다.

네트스케이프 서버: 이 주제에 관한 정보는 다음에 존재합니다: http://home.netscape.com/comprod/server_central/support/fasttrack_man/programs.htm#1010870


8.2. 제한없이 키눌림을 점검하는 법?

msvcrt 모듈을 사용하세요. 이것은 파이썬 1.5이상에서 표준 윈도우-종속적 확장입니다. 그 모듈은 함수 kbhit()을 정의하여 키보드 눌림이 있는지를 점검합니다; 또한 getch()로는 반향없이 하나의 문자를 얻습니다. 그것 말고도 다른 훌륭한 것들이 많습니다.

("keypress"를 탐색하여 유닉스를 위한 해답을 찾아 보세요.)


8.3. $PYTHONPATH

MS-DOS 에서 파생된 환경에서 사용되는, $PYTHONPATH와 같은 유닉스 명령어는 PYTHONPATH로, 달러 표시 없이 설정합니다. PYTHONPATH는 라이브러리 파일의 위치를 지정하는데에 유용합니다.


8.4. 내어쓰기 구문 에러

FAQ 는 탭을 상용하는 것을 권장하지 않습니다, 그리고 귀도의 파이썬 스타일 가이드는 4 개의 공백을 배포된 파이썬 코드에 권장합니다; 이것은 또한 Emacs의 파이썬 모드의 기본값입니다; 다음을 참조하세요

    essays/styleguide.html
어떤 에디터에서도 탭과 공백을 혼용하는 것은 좋지 않은 생각입니다. MSVC 역시 이런 관점에서 보면 다르지 않습니다, 그리고 쉽게 공백을 사용하도록 설정되어 있습니다: Tools -> Options -> Tabs를 선택하시고, 파일 타입 "Default"에 "탭 크기(Tab size)"와 "들여쓰기 크기(Indent size)"를 4로 설정하시고, 그리고 "공백 삽입(Insert spaces)" 라디오 버튼을 선택하세요.

앞쪽의 공백에서 탭과 공백의 혼용이 문제를 일으키는지 의심되시면, 파이썬을 -t 스위치로 실행하시던가, Tools/Scripts/tabnanny.py를 실행시켜서 일괄처리 모드로 디렉토리 트리를 점검하세요. .


8.5. 윈도우에서 어떻게 os.kill()을 흉내내나요?

win32api를 사용하세요:

    def kill(pid):
        """kill function for Win32"""
        import win32api
        handle = win32api.OpenProcess(1, 0, pid)
        return (0 != win32api.TerminateProcess(handle, 0))


8.6. 왜 os.path.isdir()이 NT 공유 디렉토리에서 실패하는지요?

해답은 항상 "\\"를 공유 드라이브의 마지막에 추가하는 것입니다.

  >>> import os
  >>> os.path.isdir( '\\\\rorschach\\public')
  0
  >>> os.path.isdir( '\\\\rorschach\\public\\')
  1
[블레이크 윈튼 (Blake Winton)의 대답] 공유 드라이브의 디렉토리에서 "Start >> Run"을 수행하려고 할 때 같은 문제가 있었습니다. 만약 "\\rorschach\public"를 사용했다면, 실패했을 것이지만, \\rorschach\public\"를 사용하면, 그것은 작동할 것입니다. 그 문제에 관하여는, os.stat() 역시 같습니다 (자, "\\\\rorschach\\public"에 대하여 에러 메지지를 내지만, 여러분은 이해하실 겁니다)...

이러한 일이 일어나는 것에 관하여 나름대로의 이론이 있지만, 그것은 단지 이론일 뿐입니다. NT 공유 디렉토리, 그리고 일반적인 디렉토리 사이의 차이를 이해해야 합니다. "\\rorschach\public"는 디렉토리가 아니라, 그것은 _실제로는_ IPC를 본뜬 것입니다. 이것은 일종의 양도된 신용으로서, 네트워크 드라이브를 짝짓기할 때에, "\\rorschach\public\utils"이 아니라 오로지 "\\rorschach\public"으로만 짝지을 수 있다는 사실에 근거하고 있습니다.

[funkster@midwinter.com의 해설] 그것은 실제로는 파이썬의 문제가 아닙니다, 파이썬은 잘 작동합니다; 다음은 윈도우의 네트워크 드라이브에 관하여 약간은 혼란스러운 것들을 깨끗이 정리하고 있습니다.

드라이브 문자 처럼 공유 요점을 생각해 보면 도움이 됩니다. 예제:

        k:         디렉토리가 아니다
        k:\        디렉토리이다
        k:\media   디렉토리이다
        k:\media\  디렉토리가 아니다
"k:"를 "\\conky\foo"로 대체할 때에도 같은 규칙이 적용됩니다:
        \\conky\foo          디렉토리가 아니다
        \\conky\foo\         디렉토리이다
        \\conky\foo\media    디렉토리이다
        \\conky\foo\media\   디렉토리가 아니다


8.7. PyRun_SimpleFile()이 윈도우에서 충돌하지만 유닉스에서는 그렇지 않습니다

파이썬을 내장한 어플리케이션을 윈도우로 이식하면 유닉스에서는 잘 작동하던 PyRun_SimpleFile()이 실패한다는 많은 보고를 보아 왔습니다. PyRun_SimpleString()은 두 플랫폼 모두에서 잘 작동합니다.

제가 생각하기로 이것은 그 어플리케이션이 Python15.DLL과는 다른 종류의 컴파일러 깃발 모둠으로 컴파일 되었기 때문에 발생합니다.어떤 컴파일러 깃발들은 표준 I/O 라이브러리에 영향을 미치는 것으로 판단되는데 그러한 방식으로 다른 깃발을 사용하면 호출을 실패하도록 만드는 것 같습니다. 그것을 비-디버그 다중-쓰레드 DLL로 설정할 필요가 있습니다 (명령어 라인에서 /MD를 설정하거나, 프로젝트 설정하에서 MSVC를 통하여 설정될 수 있습니다 -> C++/Code 생성 그리고 "Use rum-time library" 선택.)

또 주목할 것은 디버그를 배포 버전에 혼합-일치할수 없다는 것입니다. 만약 디버그 다중 쓰레드 DLL을 사용하기를 원하시면, 모듈에는 _반드시_ "_d"가 기본 이름에 추가되야 합니다.


8.8. _tkinter 수입이 윈도우 95/98에서 실패합니다

때로는, _tkinter 수입이 윈도우 95 또는 98에서 실패하는데, 다음과 같은 메시지로 불평합니다:

  ImportError: DLL load failed: One of the library files needed
  to run this application cannot be found. - 
  이 어플리케이션을 실행하는데 필요한 라이브러리 파일중 하나를 찾을 수 없습니다.
아마도 Tcl/Tk를 설치하지 않았을 수도 있습니다, 그러나 분명히 Tcl/Tk를 설치하셨고, 원하는 어플리케이션이 정확하게 작동하면, 문제는 아마도 설치기가 autoexec.bat 파일을 정확하게 수정하지 않았을 수 있습니다. 설치기는 PATH 환경 변수를 Tcl/Tk의 'bin' 하부디렉토리를 포함하도록 변경하는 문장을 추가하려고 합니다, 그러나 때로는 이 편집이 잘 작동하지 않습니다. 노트패드로 그것을 열어보면 무엇이 문제인지 보통은 알 수 있습니다.

(또 하나의 추가 힌트라면, 데이비드 자프란스키(David Szafranski)가 지적한 바에 의하면: 여러분은 여기에서 긴 파일이름을 사용할 수 없습니다; 예를 들어. C:\Program Files\Tcl\bin 대신에 C:\PROGRA~1\Tcl\bin을 사용하세요)


8.9. 내려 받은 문서를 윈도우에서 추출할 수 없습니다

가끔, 문서 패키지를 윈도우 머신에 웹 브라우저를 사용하여 내려 받을 때, 그 저장된 파일의 확장자가 .EXE로 끝납니다. 이것은 실수입니다; 확장자는 .TGZ가 되어야 합니다.

간단히 내려받은 파일을 확장자가 .TGZ가 되도록 다시 이름지으세요, 그러면 WinZip이 그것을 처리할 것입니다. (만약 WinZip이 그렇게 하지 못하면, 더 새로운 버전을 다음에서 내려 받으세요 (http://www.winzip.com/.)


8.10. Py_RunSimpleFile()를 작동시킬 수 없습니다.

이것은 컴파일러 벤더, 버전 그리고 (아마도) 선택사항에도 대단히 민감한 문제입니다 만약 여러분의 내장 프로그램에 있는 FILE* 구조가 파이썬 인터프리터가 가정한 것과 동일하지 않다면 그것은 작동하지 않을 것입니다.

파이썬 1.5.* (python15.dll) DLL들은 모두 MS VC++ 5.0과 multithreading-DLL 선택사항(아마도, /MD)으로 컴파일 됩니다.

컴파일러 혹은 깃발을 변경할 수 없다면, Py_RunSimpleString()을 사용해 보세요. 임의의 파일을 실행하도록 만드는 꼼수는 여러분의 파일이름을 인수로 주어 execfile()를 호출하도록 구성하는 것입니다.


8.11. 윈도우를 위한 Freeze는 어디에 있나요?

("Freeze"는 파이썬 프로그램을 독립적인 하나의 실행파일로 적재해 주는 프로그램입니다. 컴파일러가 아니며, 프로그램이 더 빨라지지는 않습니다, 그렇지만 (같은 운영체제와 CPU를 가진 플랫폼에) 좀 더 쉽게 배포가능합니다. 더 자세한 사항을 원하시면 그 프로그램의 README파일을 보십시요.)

윈도우에서 freeze를 사용할 수는 있지만, 소스를 내려 받아야만 합니다 (http://www.python.org/download/download_source.html를 참조하세요). 이것은 파이썬 1.5.2 (그 이후의 버전)에만 권장합니다; 더 오래된 버전은 잘 작동하지 않습니다.

마이크로소프트 VC++ 5.0 컴파일러가 필요합니다 (아마 6.0에도 역시 작동할 것입니다). 파이썬을 구축할 필요가 있습니다 -- 프로젝트 파일들은 모두 PCbuild 디렉토리에 존재합니다.

freeze 프로그램은 그 소스트리의 Tools\freeze 하부디렉토리에 있습니다.


8.12. *.pyd 파일은 DLL과 같은 건가요?

그렇습니다, .pyd 파일은 dll입니다. 그러나 약간의 차이는 있습니다. foo.pyd라는 이름의 DLL을 가지고 계신다면, 그 파일은 반드시 함수 initfoo()를 가지고 있어야 합니다. 그러면 파이썬에 "import foo"를 작성할 수 있고, 파이썬은 foo.pyd를 탐색할 것입니다 (뿐만아니라 foo.py, foo.pyc도 탐색합니다) 그리고 발견한다면, 초기화를 하기 위하여 initfoo()를 호출하려고 합니다. .exe를 foo.lib와 연결해 놓지 않았다면, 윈도우는 반드시 그 DLL이 존재하기를 요구할 것입니다.

주목할 것은 foo.pyd에 대한 탐색 경로는 PYTHONPATH이며, 윈도우 사용자가 foo.dll을 탐색하기 위하여 사용하는 그 경로와는 같지 않다는 것입니다. 또한, foo.pyd는 프로그램을 실행하기 위하여 존재해야 할 필요는 없습니다, 반면에 프로그램을 dll과 연결해 놓았다면, 그 dll은 필수적으로 있어야 합니다. 물론, foo.pyd는 "import foo"를 사용하기를 원한다면 필요합니다. dll에서, 연결은 소스코드에 __declspec(dllexport)으로 선언됩니다. .pyd에서, 연결은 이용가능한 함수들의 목록안에 정의됩니다.


8.13. cw3215mt.dll 분실 (또는 cw3215.dll발견 불능)

윈도우에서 Tkinter를 사용할 때, 가끔씩, cw3215mt.dll 또는 cw3215.dll이 없다는 에러 메시지를 맞이합니다.

원인: 구형 Tcl/Tk DLL을 여러분의 경로 (아마도 C:\Windows)에 있는 cygwin으로 구축했습니다. Tcl/Tk 표준 설치에 있는 Tcl/Tk DLL을 사용해야 합니다. (파이썬 1.5.2에 함께 딸려옵니다).


8.14. 파이썬 스크립트를 실행파일로 만드는 법:

[블레이크 커버렛(Blake Coverett)]

Win2K:

표준 설치기는 이미 .py 확장자를 파일 타입(Python.File)에 연결해 두고 있습니다 그리고 그 파일 타입에 인터프리터를 실행하는 개방 명령어를 할당합니다 (D:\Program Files\Python\python.exe "%1" %*). 이것으로 충분히 스크립트 파일을 명령어 프롬프트에서 'foo.py'로 실행가능하게 할 수 있습니다. 만약 확장자 없이 단순히 'foo'라고 타자함으로써 그 스크립트를 실행할 수 있기를 원한다면 .py를 PATHEXT 환경 변수에 추가할 필요가 있습니다.

WinNT:

위에 전술한대로 설치된 단계를 거쳐서 스크립트를 'foo.py'로 실행할 수 있습니다, 그러나 NT 명령어 처리기의 고질적인 버그로 이런식으로 실행된 스크립트의 입력과 출력을 방향전환할 수 없습니다. 이것은 때로 중요한 문제입니다.

WinNT하에서 파이썬 스크립트를 실행가능하게 하는 적절한 마법이라면 그 파일에 확장자 .cmd를 할당하고 다음을 첫 번째 라인으로 추가하는 것입니다:

    @setlocal enableextensions & python -x %~f0 %* & goto :EOF
Win9x:

[브루스 에켈(Bruce Eckel)의 배려]

  @echo off
  rem = """
  rem run python on this bat file. Needs the full path where
  rem you keep your python files. The -x causes python to skip
  rem the first line of the file:
  python -x c:\aaa\Python\\"%0".bat %1 %2 %3 %4 %5 %6 %7 %8 %9
  goto endofpython
  rem """
  # The python program goes here:
  print "hello, Python"
  # For the end of the batch file:
  rem = """
  :endofpython
  rem """


8.15. 설치기로 부터의 CTL3D32 버전에 관한 경고

파이썬 설치기는 다음과 같은 경고를 냅니다:

  이 버전은 CTL3D32.DLL을 사용하며 올바른 버전이 아닙니다.
  이 버전은 윈도우 NT 어플리케이션에만 사용될 수 있습니다.
[팀 피터스(Tim Peters)] 이것은 Microsoft DLL로서, 문제의 근원으로 악명 높습니다. 이 메시지가 뜻하는 바는: 여러분의 운영체제에 이 DLL이 맞지 않는 버전을 가지고 있다는 뜻입니다. 파이썬 설치로는 이러한 것을 야기 하지 않습니다 -- 이 전에 설치한 다른 어떤 것이 운영체제에 딸려온 DLL을 덮어썼을 것입니다. (아마도 오래된 쉐어웨어 종류일겁니다, 그러나 지금으로서는 말할 방법이 없습니다). 만약 "CTL3D32"을 (예를 들어, 알타비스타 같은) 다른 검색 엔진 사용하여 검색해보면, 수백 수천의 웹페이지에서 모든 종류의 설치 프로그램에서 같은 문제에 관하여 불평하고 있는 것을 보실 수 있습니다. 그것들을 보시면 여러분의 시스템에 정확한 버전을 재설치하는 방법을 아실 수 있을 겁니다. (파이썬이 이 문제를 야기하는 것이 아니기 때문에, 우리는 문제를 해결할 수 없습니다).

데이비드 에이 버튼(David A Burton)이 이 문제를 해결하는 작은 프로그램을 작성하였습니다. http://www.burtonsys.com/download.html에 가셔서 "ctl3dfix.zip"에 딸깍해보세요.


8.16. 어떻게 파이썬을 윈도우의 어플리케이션안으로 내장할 수 있는가?

Edward K. Ream <edream@tds.net> 씀

파이썬 인터프리터를 윈도우 어플리케이션에 내장하는 것은 다음과 같이 요약될 수 있습니다:

1. 파이썬을 여러분의 .exe 파일 안으로 직접적으로 구축해 넣지 마세요. 윈도우에서는, 파이썬은 반드시 DLL이 되어야 그 자체로 DLL인 모듈들을 수입할 수 있습니다. (이것이 가장 중요한 문서화되지 않은 사실입니다.) 대신에, python15.dll에 연결하세요; 그것은 전형적으로 c:\Windows\System에 설치됩니다.

파이썬에 정적 혹은 동적으로 연결할 수 있습니다. 정적으로 연결한다는 것은 python15.lib에 대하여 연결한다는 것을 의미합니다. 결점은, 만약 시스템에 python15.dll이 존재하지 않는다면 어플리케이션이 작동하지 않는다는 것입니다.

일반적 주의: python15.lib은 python.dll에 상응하여 이른바 "import lib"으로 불리웁니다. 그것은 단순히 연결자를 위하여 심볼을 정의할 뿐입니다.

볼랜드사의 주의: python15.lib를 Coff2Omf.exe을 사용하여 먼저 OMF 포맷으로 변환하세요.

동적으로 연결하게 되면 연결 선택사항들을 대단히 단순하게 할 수 있습니다; 모든 것은 실행시에 일어납니다. 여러분의 코드는 python15.dll을 윈도우의 LoadLibraryEx 루틴을 사용하여 적재하여야 합니다. 그 코드는 또한 윈도우의 GetProcAddress 루틴에 의하여 획득된 포인터를 사용하여 python15.dll에 있는 접근 루틴과 데이타를 (즉 다시 말하면, 파이썬의 C API를) 사용하여야 합니다. 마크로는 이러한 포인터를 파이썬의 C API에 있는 루틴을 호출하는 어떠한 C 코드에도 투명하게 사용할 수 있습니다.

2. SWIG을 사용하신다면, 파이썬의 "확장 모듈"을 작성하는 것이 쉬운데 어플의 데이타와 메쏘드를 파이썬에서 사용가능하도록 만들어 줍니다. SWIG은 여러분을 대신하여 골치아픈 모든 문제들을 처리해 줄 것입니다. 그 결과는 C 코드로서 _여러분의 .exe 파일에_ 연결하여 준 것입니다.(!) DLL파일을 만들 필요는 _없습니다_, 그리고 이것은 연결하는 것을 간단하게 하여 줍니다.

3. SWIG은 초기화 함수 하나(C 함수)를 만들 것이데 그 이름은 그 확장 모듈의 이름에 달려 있습니다. 예를 들어, 그 모듈의 이름이 leo라면, 그 초기화 함수는 initleo()라고 불리워질 것입니다. 만약 SWIG shadow 클래스를 사용하신다면, 그렇게 사용하셔야 하는데, 그 초기화 함수는 initleoc()라고 불리워질 것입니다. 이것은 깊숙히 숨은 helper 클래스를 초기화 하는데 그 클래스는 shadow 클래스가 사용합니다.

그 C 코드를 2단계에서 여러분의 .exe 파일에 연결할 수 있는 이유는 그 초기화 함수를 호출하는 것이 그 모듈을 파이썬으로 수입하는 것과 동일하기 때문입니다! (이것이 두 번째의 문서화 되지 않은 중요 사실입니다.)

4. 요약하면, 다음의 코드를 사용하여 파이썬 인터프리터를 여러분의 확장 모듈로 초기화할 수 있습니다.

    #include "python.h"
    ...
    Py_Initialize();  // Initialize Python.
    initmyAppc();  // Initialize (import) the helper class.
    PyRun_SimpleString("import myApp") ;  // Import the shadow class.
5. Python의 C API에는 두 개의 문제가 있는데 MSVC 말고 다른 컴파일러를 사용해 보시면 그 문제는 명백해 집니다, MSVC 컴파일러는 python15.dll을 구축하는데 사용되었었습니다.

첫번째 문제: FILE * 인수를 취하는, 이른바 "대단히 고 수준"의 함수는 다중-컴파일러 환경에서는 작동하지 않을 것입니다; 각 컴파일러가 FILE 구조를 인식하는 것이 달라질 것입니다. 경고가 파이썬 문서에 추가되어야 할 것입니다! 구현의 관점에서 보면 이러한 것들은 대단히_저_ 수준 함수 입니다.

두 번째 문제: SWIG은 void 함수에 대한 포장자를 생성할 때 다음의 코드를 생성합니다:

    Py_INCREF(Py_None);
    _resultobj = Py_None;
    return _resultobj;
안타깝게도, Py_None은 매크로로서 python15.dll 안에서 _Py_NoneStruct라고 불리우는 복잡한 데이타 구조를 참조하도록 확장됩니다. 이제, 이 코드는 다중-컴파일러 환경에서는 실패할 것입니다. 그러한 코드를 다음과 같이 대체하세요:

        return Py_Build("");
SWIG의 %typemap 명령어를 사용하여 그 변경을 자동적으로 하는 것도 가능할 것입니다, 그렇지만 저는 이것을 아직까지 작동시키지 못하고 있습니다 (저는 완전히 SWIG 초보입니다.)

6. 파이썬의 쉘 스크립트를 사용하여 파이썬 인터프리터를 여러분의 윈도우 어플 안에서 띄우는 것은 바람직한 생각이 아닙니다; 결과로 나오는 그 창은 여러분의 어플의 윈도우 시스템에 독립적이 될 것입니다. 오히려, 여러분은 (혹은 wxPythonWindow 클래스)는 "고유의" 인터프리터 윈도우를 생성해야만 합니다. 그 윈도우를 용이하게 파이썬 인터프리터에 연결할 수 있습니다. 파이썬의 i/o를 읽고 쓰기를 지원하는 _어떤_ 객체에도 방향 전환할 수 있습니다, 그러므로 여러분이 필요한 것은 (확장 모듈에 정의된) 읽기 쓰기 메쏘드를 담고 있는 파이썬 객체입니다.


앞으로    목차    1    2    3    4    5    6    7    제8장    다음으로