پرسش‌های متداول درباره‌ی پایتون در ویندوز

چگونه یک برنامه پایتون را در ویندوز اجرا کنم؟

این لزوماً پرسش ساده‌ای نیست. اگر از قبل با اجرای برنامه‌ها از طریق خط فرمان ویندوز آشنا هستید، همه‌چیز بدیهی به نظر خواهد رسید؛ در غیر این صورت، ممکن است به کمی راهنمایی بیشتری نیاز داشته باشید.

مگر اینکه از نوعی محیط توسعه یکپارچه استفاده کنید، در نهایت دستورات ویندوز را در آنچه «پنجره خط فرمان» نامیده می‌شود، تایپ خواهید کرد. معمولاً می‌توانید چنین پنجره‌ای را از نوار جست‌وجوی خود با جست‌وجوی cmd ایجاد کنید. باید بتوانید تشخیص دهید که چنین پنجره‌ای را راه‌اندازی کرده‌اید، زیرا «خط فرمان» ویندوز را خواهید دید که معمولاً به این شکل است:

C:\>

ممکن است حرف متفاوت باشد و ممکن است چیزهای دیگری بعد از آن وجود داشته باشد، بنابراین ممکن است به‌همین‌آسانی چیزی مانند این را ببینید:

D:\YourName\Projects\Python>

بسته به این که رایانه‌ی شما چگونه پیکربندی شده است و اخیراً چه کارهای دیگری با آن انجام داده‌اید. پس از راه‌اندازی چنین پنجره‌ای، به‌خوبی در مسیر اجرای برنامه‌های پایتون هستید.

باید بدانید که اسکریپت‌های پایتون شما باید به‌وسیله‌ی برنامه‌ی دیگری به نام مفسر پایتون پردازش شوند. مفسر اسکریپت شما را می‌خواند، آن را به بایت‌کدها کامپایل می‌کند و سپس بایت‌کدها را اجرا می‌کند تا برنامه‌ی شما اجرا شود. بنابراین، چگونه ترتیب می‌دهید که مفسر پایتون شما را پردازش کند؟

ابتدا باید اطمینان حاصل کنید که پنجره خط فرمان شما واژه «py» را به‌عنوان دستوری برای راه‌اندازی مفسر می‌شناسد. اگر یک پنجره خط فرمان باز کرده‌اید، باید فرمان py را وارد کرده و کلید بازگشت را بزنید:

C:\Users\YourName> py

سپس باید چیزی شبیه به این ببینید:

Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

شما مفسر را در «حالت تعاملی» راه‌اندازی کرده‌اید. این بدان معناست که می‌توانید دستورها یا عبارت‌های Python را به‌صورت تعاملی وارد کنید و در حالی که منتظر می‌مانید، آن‌ها اجرا یا ارزیابی شوند. این یکی از قوی‌ترین ویژگی‌های Python است. با وارد کردن چند عبارت دلخواه خود و دیدن نتایج، آن را بررسی کنید:

>>> print("Hello")
Hello
>>> "Hello" * 3
'HelloHelloHello'

بسیاری از افراد از حالت تعاملی به‌عنوان ماشین‌حسابی راحت و در عین حال بسیار برنامه‌پذیر استفاده می‌کنند. هنگامی که می‌خواهید نشست تعاملی پایتون خود را پایان دهید، تابع exit() را فراخوانی کنید یا کلید Ctrl را پایین نگه دارید و همزمان Z را وارد کنید، سپس کلید "Enter" را فشار دهید تا به خط فرمان ویندوز خود بازگردید.

ممکن است همچنین یک ورودی منوی Start مانند Start ‣ Programs ‣ Python 3.x ‣ Python (command line) داشته باشید که باعث می‌شود اعلان >>> را در پنجره‌ای جدید ببینید. در این صورت، پنجره پس از اینکه تابع exit() را فراخوانی کنید یا نویسه‌ی Ctrl-Z را وارد کنید ناپدید خواهد شد؛ ویندوز در حال اجرای یک فرمان "python" واحد در پنجره است و هنگامی که مفسر را خاتمه دهید، آن را می‌بندد.

اکنون که می‌دانیم دستور py شناخته می‌شود، می‌توانید اسکریپت پایتون خود را به آن بدهید. شما باید مسیر مطلق یا نسبی اسکریپت پایتون را به آن بدهید. فرض کنید اسکریپت پایتون شما روی دسکتاپ شما قرار دارد و نام آن hello.py است، و خط فرمان شما به‌خوبی در پوشه خانه شما باز است، بنابراین چیزی مشابه زیر را می‌بینید:

C:\Users\YourName>

بنابراین اکنون با تایپ py و سپس مسیر اسکریپت‌تان، از دستور py می‌خواهید که اسکریپت شما را به پایتون بدهد:

C:\Users\YourName> py Desktop\hello.py
hello

چگونه اسکریپت‌های پایتون را قابل‌اجرا کنم؟

در ویندوز، نصب‌کننده استاندارد پایتون از قبل پسوند .py را به یک نوع پرونده (Python.File) مرتبط می‌کند و به آن نوع پرونده یک دستور باز کردن می‌دهد که مفسر را اجرا می‌کند (D:\Program Files\Python\python.exe "%1" %*). این کافی است تا اسکریپت‌ها از خط فرمان به‌صورت 'foo.py' قابل اجرا شوند. اگر ترجیح می‌دهید بتوانید اسکریپت را صرفاً با تایپ 'foo' بدون پسوند اجرا کنید، باید .py را به متغیر محیطی PATHEXT اضافه کنید.

چرا راه‌اندازی پایتون گاهی اوقات این‌قدر طول می‌کشد؟

معمولاً پایتون در ویندوز بسیار سریع راه‌اندازی می‌شود، اما گاهی گزارش‌هایی از اشکال وجود دارد که راه‌اندازی پایتون ناگهان زمان‌بر می‌شود. این موضوع حتی گیج‌کننده‌تر می‌شود، زیرا پایتون در سایر سیستم‌های ویندوزی که به نظر می‌رسد پیکربندی یکسانی دارند، به‌خوبی کار می‌کند.

ممکن است این مشکل به دلیل پیکربندی نادرست نرم‌افزار ضدویروس روی سیستم مشکل‌دار باشد. شناخته شده است که برخی اسکنرهای ضدویروس، وقتی اسکنر برای پایش تمام خواندن‌ها از سامانه فایل‌بندی پیکربندی شود، سربار راه‌اندازی را تا ۲ مرتبه بزرگی افزایش می‌دهند. پیکربندی نرم‌افزار اسکن ضدویروس روی سیستم‌های خود را بررسی کنید تا اطمینان حاصل شود که واقعاً به‌طور یکسان پیکربندی شده‌اند. McAfee، وقتی برای اسکن تمام فعالیت‌های خواندن سامانه فایل‌بندی پیکربندی شود، به‌طور ویژه‌ای مشکل‌ساز است.

چگونه از یک اسکریپت پایتون یک پرونده اجرایی بسازم؟

برای فهرستی از ابزارهایی که می‌توان برای ساخت پرونده‌های اجرایی از آن‌ها استفاده کرد، چگونه می‌توانم از یک اسکریپت پایتون یک دودویی مستقل بسازم؟ را ببینید.

آیا پرونده *.pyd همان DLL است؟

بله، پرونده‌های .pyd، DLL هستند، اما چند تفاوت وجود دارد. اگر یک DLL با نام foo.pyd دارید، باید تابعی به نام PyInit_foo() داشته باشد. سپس می‌توانید در پایتون «import foo» را بنویسید، و پایتون foo.pyd (و همچنین foo.py و foo.pyc) را جستجو می‌کند و در صورت یافتن آن، تلاش می‌کند PyInit_foo() را فراخوانی کند تا آن را مقداردهی اولیه کند. شما پرونده .exe خود را با foo.lib پیوند نمی‌دهید، زیرا این کار باعث می‌شود ویندوز نیازمند موجود بودن DLL باشد.

توجه داشته باشید که مسیر جستجو برای foo.pyd، PYTHONPATH است و با مسیری که ویندوز برای جستجوی foo.dll از آن استفاده می‌کند، یکسان نیست. همچنین، برای اجرای برنامه‌تان لازم نیست foo.pyd وجود داشته باشد، در حالی که اگر برنامه‌تان را با یک DLL پیوند داده باشید، آن DLL مورد نیاز است. البته، اگر بخواهید import foo را بنویسید، foo.pyd مورد نیاز است. در یک DLL، پیوند در کد منبع با __declspec(dllexport) اعلام می‌شود. در یک .pyd، پیوند در فهرستی از توابع موجود تعریف می‌شود.

چگونه می‌توانم پایتون را در یک برنامه ویندوزی تعبیه کنم؟

تعبیه مفسر پایتون در یک برنامه ویندوزی را می‌توان به‌صورت زیر خلاصه کرد:

  1. پایتون را مستقیماً در پرونده .exe خود قرار ندهید. در ویندوز، پایتون باید یک DLL باشد تا بتواند ایمپورت ماژول‌هایی را که خودشان DLL هستند مدیریت کند. (این نخستین نکته کلیدی مستندنشده است.) در عوض، به pythonNN.dll پیوند دهید؛ این پرونده معمولاً در C:\Windows\System نصب شده است. NN نسخه پایتون است، عددی مانند «33» برای پایتون 3.3.

    شما می‌توانید به دو روش مختلف به Python پیوند بدهید. پیوند در زمان بارگذاری به معنای پیوند دادن با pythonNN.lib است، در حالی که پیوند در ران‌تایم به معنای پیوند دادن با pythonNN.dll است. (نکته عمومی: pythonNN.lib به‌اصطلاح کتابخانه ایمپورت (import lib) متناظر با pythonNN.dll است. این پرونده صرفاً نمادها را برای پیونددهنده تعریف می‌کند.)

    پیوندسازی در ران‌تایم، گزینه‌های پیوند را به‌طور چشمگیری ساده می‌کند؛ همه‌چیز در ران‌تایم اتفاق می‌افتد. کد شما باید pythonNN.dll را با استفاده از روتین LoadLibraryEx() ویندوز بارگذاری کند. این کد همچنین باید از روتین‌های دسترسی و داده‌های موجود در pythonNN.dll (یعنی API C پایتون) از طریق اشاره‌گرهای دریافت‌شده از روتین GetProcAddress() ویندوز استفاده کند. ماکروها می‌توانند استفاده از این اشاره‌گرها را برای هر کد C که روتین‌های API C پایتون را فراخوانی می‌کند، شفاف کنند.

  2. اگر از SWIG استفاده کنید، ایجاد یک «ماژول توسعه‌ای» برای پایتون آسان است که داده‌ها و متدهای برنامه را در دسترس پایتون قرار می‌دهد. SWIG تقریباً تمام جزئیات ناخوشایند را برای شما مدیریت می‌کند. نتیجه کد C است که شما آن را به درون پرونده .exe خود پیوند می‌دهید (!) شما نیازی به ایجاد یک پرونده DLL ندارید، و این موضوع نیز پیوند دادن را ساده‌تر می‌کند.

  3. SWIG یک تابع مقداردهی اولیه (یک تابع C) ایجاد می‌کند که نام آن به نام ماژول الحاقی بستگی دارد. برای مثال، اگر نام ماژول leo باشد، تابع مقداردهی اولیه با نام initleo() خواهد بود. اگر از کلاس‌های سایه SWIG (shadow classes) استفاده کنید، همان‌طور که باید، تابع مقداردهی اولیه با نام initleoc() خواهد بود. این تابع یک کلاس کمکی عمدتاً پنهان را مقداردهی اولیه می‌کند که توسط کلاس سایه استفاده می‌شود.

    دلیل اینکه می‌توانید کد C را در مرحله‌ی ۲ به پرونده .exe خود پیوند دهید این است که فراخوانی تابع مقداردهی اولیه معادل ایمپورت کردن ماژول به پایتون است! (این دومین واقعیت کلیدی مستندنشده است.)

  4. به‌طور خلاصه، می‌توانید از کد زیر برای مقداردهی اولیه مفسر پایتون با ماژول توسعه‌ای خود استفاده کنید.

    #include <Python.h>
    ...
    Py_Initialize();  // Initialize Python.
    initmyAppc();  // Initialize (import) the helper class.
    PyRun_SimpleString("import myApp");  // Import the shadow class.
    
  5. دو مشکل در C API پایتون وجود دارد که اگر از کامپایلری غیر از MSVC، کامپایلری که برای ساخت pythonNN.dll استفاده شده است، استفاده کنید، آشکار خواهند شد.

    مشکل ۱: به‌اصطلاح توابع «بسیار سطح بالا» که آرگومان‌های FILE * می‌گیرند، در محیطی با چند کامپایلر کار نخواهند کرد، زیرا درک هر کامپایلر از struct FILE متفاوت خواهد بود. از دیدگاه پیاده‌سازی، این‌ها توابع بسیار سطح پایینی هستند.

    مشکل ۲: SWIG هنگام تولید پوشش‌ها برای توابع void، کد زیر را تولید می‌کند:

    Py_INCREF(Py_None);
    _resultobj = Py_None;
    return _resultobj;
    

    متأسفانه، Py_None یک ماکرو است که به ارجاعی به یک ساختار داده پیچیده به نام _Py_NoneStruct در pythonNN.dll بسط می‌یابد. باز هم، این کد در یک محیط چندکامپایلری شکست خواهد خورد. چنین کدی را با این جایگزین کنید:

    return Py_BuildValue("");
    

    ممکن است بتوان از دستور %typemap مربوط به SWIG برای ایجاد تغییر به‌صورت خودکار استفاده کرد، هرچند من نتوانسته‌ام آن را به کار بیندازم (من در SWIG کاملاً تازه‌کار هستم).

  6. استفاده از یک اسکریپت پوسته پایتون برای باز کردن یک پنجره‌ی مفسر پایتون از داخل برنامه‌ی ویندوزی شما ایده‌ی خوبی نیست؛ پنجره‌ی حاصل، مستقل از سیستم پنجره‌بندی برنامه‌ی شما خواهد بود. در عوض، شما (یا کلاس wxPythonWindow) باید یک پنجره‌ی مفسر «بومی» ایجاد کنید. اتصال آن پنجره به مفسر پایتون آسان است. شما می‌توانید ورودی/خروجی پایتون را به _هر_ شیء که از read و write پشتیبانی می‌کند تغییر مسیر دهید، بنابراین تنها چیزی که نیاز دارید، یک شیء پایتون (تعریف‌شده در ماژول توسعه شما) است که شامل متدهای read() و write() باشد.

چگونه از درج تب‌ها توسط ویرایشگرها در کد منبع پایتون خود جلوگیری کنم؟

در پرسش‌های متداول، استفاده از تب‌ها توصیه نمی‌شود، و راهنمای سبک پایتون، PEP 8، برای کد پایتون توزیع‌شده ۴ فاصله را توصیه می‌کند؛ این، پیش‌فرض python-mode در Emacs نیز هست.

در هر ویرایشگری، ترکیب تب‌ها و فاصله‌ها ایده خوبی نیست. MSVC در این زمینه تفاوتی ندارد و به‌راحتی برای استفاده از فاصله‌ها پیکربندی می‌شود: Tools ‣ Options ‣ Tabs را انتخاب کنید، و برای نوع پرونده "Default" مقادیر "Tab size" و "Indent size" را روی ۴ تنظیم کنید و دکمه رادیویی "Insert spaces" را انتخاب کنید.

پایتون در صورتی که ترکیبی از تب‌ها و فاصله‌ها در فضای سفید ابتدایی مشکل ایجاد کند، IndentationError یا TabError را پرتاب می‌کند. همچنین می‌توانید ماژول tabnanny را برای بررسی یک درخت پوشه در حالت دسته‌ای اجرا کنید.

چگونه بدون مسدود شدن، فشردن یک کلید را بررسی کنم؟

از ماژول msvcrt استفاده کنید. این یک ماژول توسعه‌ای استاندارد مختص ویندوز است. این ماژول تابع kbhit() را تعریف می‌کند که بررسی می‌کند آیا ضربه‌ای به صفحه‌کلید وارد شده است یا خیر، و getch() که یک نویسه را بدون بازتاب آن دریافت می‌کند.

چگونه خطای نبود api-ms-win-crt-runtime-l1-1-0.dll را برطرف کنم؟

این موضوع ممکن است در پایتون 3.5 و نسخه‌های جدیدتر، هنگام استفاده از ویندوز 8.1 یا نسخه‌های قدیمی‌تر بدون نصب همه به‌روزرسانی‌ها رخ دهد. ابتدا اطمینان حاصل کنید که سیستم‌عامل شما پشتیبانی می‌شود و به‌روز است، و اگر این کار مشکل را حل نکرد، برای راهنمایی درباره نصب دستی به‌روزرسانی C Runtime، به صفحه پشتیبانی مایکروسافت مراجعه کنید.