วิธีหลีกเลี่ยงไฟล์. pyc


268

ฉันสามารถรัน python interpreter โดยไม่สร้างไฟล์. pyc ที่คอมไพล์ได้หรือไม่?

คำตอบ:


288

จาก"มีอะไรใหม่ใน Python 2.6 - การเปลี่ยนแปลงของล่าม" :

Python สามารถป้องกันได้จากการเขียนไฟล์. pyc หรือ. pyo โดยการส่งสวิตช์-Bไปยัง Python interpreter หรือโดยการตั้งค่า ตัวแปรสภาพแวดล้อมPYTHONDONTWRITEBYTECODEก่อนที่จะเรียกใช้ตัวแปล การตั้งค่านี้มีให้สำหรับโปรแกรม Python เนื่องจาก sys.dont_write_bytecodeตัวแปรและรหัส Python สามารถเปลี่ยนค่าเพื่อปรับเปลี่ยนพฤติกรรมของล่าม

ปรับปรุง 2010/11/27: งูหลาม 3.2 ที่อยู่ปัญหาของเกะกะโฟลเดอร์แหล่งที่มากับ.pycไฟล์โดยการแนะนำพิเศษ__pycache__โฟลเดอร์ย่อยให้ดูมีอะไรใหม่ในหลาม 3.2 - PYC ไดเรกทอรีพื้นที่เก็บข้อมูล


1
อย่างน้อยใน OS X 10.8 ที่รัน Python 2.7 ตัวแปรสภาพแวดล้อมจะไม่มีผล
sorin

5
หากคุณกำลังฝังตัวแปลภาษา (ในโปรแกรม C ++) ให้ใช้ "Py_DontWriteBytecodeFlag = 1;" ในซอร์สโค้ดของคุณ นั่นคือ int ระดับโลกที่ประกาศใน pydebug.h
JimB

1
ตัวแปรสภาพแวดล้อมใช้งานได้ดีสำหรับฉันใน 2.7 ไม่รู้ว่ามีปัญหาอะไรที่คนอื่นกำลังมี ขอบคุณ!
โทมัส

8
ทำงานให้ฉันด้วยบน OSX (10.8 & 10.10); @sorin คุณส่งออกตัวแปรถูกต้องหรือไม่ export PYTHONDONTWRITEBYTECODE=1
nevelis

1
คุณรู้วิธีการทำเช่นเดียวกันกับ pytest หรือไม่?

110
import sys

sys.dont_write_bytecode = True

25
ฉันเพิ่งลองและมันใช้งานได้สำหรับโมดูลที่นำเข้า โดยเฉพาะเมื่อตัวแปรนี้ถูกตั้งค่าสิ่งที่นำเข้าในภายหลังจะไม่สร้างไฟล์ pyc มันช่างน่ายินดี ขอบคุณ

แทนที่จะเพิ่มสิ่งนี้ในโมดูลผู้ปกครองลองเพิ่มสิ่งนี้ในสคริปต์อ้างอิง มันใช้งานได้ดี ขอบคุณ @te wilson
Sathy

4
เพิ่มสิ่งนี้ลงในของคุณsite-packages/usercustomize.pyเพื่อให้สิ่งนี้ใช้ได้กับสคริปต์ทั้งหมดของคุณ $HOME/.local/lib/python2.6/site-pacakges/usercustomize.pyสำหรับผมไดเรกทอรีนี้คือ cf เลย docs.python.org/2/tutorial/…
RobM

3
แพ็คเกจไซต์ของฉันอยู่ที่: /usr/local/lib/python2.7/site-packages และฉันต้องสร้าง usercustomize.py
anon58192932

3
หรือในบรรทัดเดียว:import sys; sys.dont_write_bytecode = True
ET-CS

23

จริงๆแล้วมันมีวิธีการทำใน Python 2.3+ แต่มันลึกลับเล็กน้อย ฉันไม่รู้ว่าคุณรู้สิ่งนี้หรือไม่ แต่คุณสามารถทำสิ่งต่อไปนี้:

$ unzip -l /tmp/example.zip
 Archive:  /tmp/example.zip
   Length     Date   Time    Name
 --------    ----   ----    ----
     8467  11-26-02 22:30   jwzthreading.py
 --------                   -------
     8467                   1 file
$ ./python
Python 2.3 (#1, Aug 1 2003, 19:54:32) 
>>> import sys
>>> sys.path.insert(0, '/tmp/example.zip')  # Add .zip file to front of path
>>> import jwzthreading
>>> jwzthreading.__file__
'/tmp/example.zip/jwzthreading.py'

ตามห้องสมุดzipimport :

ไฟล์ใด ๆ ที่อาจมีอยู่ในไฟล์ ZIP แต่มีเพียงไฟล์. py และ. py [co] เท่านั้นที่สามารถนำเข้าได้ ไม่อนุญาตให้นำเข้า ZIP ของโมดูลแบบไดนามิก (.pyd, .so) โปรดทราบว่าหากไฟล์เก็บถาวรมีไฟล์. py เท่านั้น Python จะไม่พยายามแก้ไขไฟล์เก็บถาวรด้วยการเพิ่มไฟล์. pyc หรือ. pyo ที่เกี่ยวข้องซึ่งหมายความว่าหากไฟล์เก็บถาวร ZIP ไม่มีไฟล์. pyc การนำเข้าอาจค่อนข้างช้า

ดังนั้นสิ่งที่คุณต้องทำคือ zip ไฟล์ขึ้นเพิ่ม zipfile ไปยัง sys.path ของคุณแล้วนำเข้า

หากคุณกำลังสร้างสิ่งนี้สำหรับ UNIX คุณอาจพิจารณาบรรจุสคริปต์ของคุณโดยใช้สูตรนี้: ปฏิบัติการยูนิกซ์ zipแต่โปรดทราบว่าคุณอาจต้องปรับแต่งสิ่งนี้หากคุณวางแผนที่จะใช้ stdin หรืออ่านอะไรจาก sys.args ทำโดยไม่มีปัญหามากเกินไป)

ในประสบการณ์การใช้งานของฉันไม่ได้รับความทุกข์ทรมานมากนักเนื่องจากสิ่งนี้ แต่คุณควรคิดสองครั้งก่อนที่จะนำเข้าโมดูลขนาดใหญ่มากด้วยวิธีนี้


11

ใน 2.5 ไม่มีวิธีที่จะระงับการใช้งานยกเว้นมาตรการที่ไม่ให้ผู้ใช้สามารถเข้าถึงไดเรกทอรีได้

อย่างไรก็ตามใน python 2.6 และ 3.0 อาจมีการตั้งค่าในโมดูล sys ชื่อ "dont_write_bytecode" ที่สามารถตั้งค่าเพื่อระงับสิ่งนี้ สิ่งนี้สามารถตั้งค่าได้โดยผ่านตัวเลือก "-B" หรือการตั้งค่าตัวแปรสภาพแวดล้อม "PYTHONDONTWRITEBYTECODE"


7

คุณสามารถตั้งค่าsys.dont_write_bytecode = Trueในแหล่งที่มาของคุณ แต่ที่จะต้องอยู่ในไฟล์หลามแรกที่โหลด หากคุณดำเนินการแล้วคุณจะไม่ได้รับpython somefile.pysomefile.pyc

เมื่อคุณติดตั้งยูทิลิตี้ที่ใช้setup.pyและentry_points=คุณจะได้ตั้งค่าsys.dont_write_bytecodeในสคริปต์เริ่มต้น ดังนั้นคุณไม่สามารถพึ่งพาสคริปต์เริ่มต้น "เริ่มต้น" ที่สร้างโดย setuptools

หากคุณเริ่มต้น Python ด้วยไฟล์ python เป็นอาร์กิวเมนต์ด้วยตัวคุณเองคุณสามารถระบุ-B:

python -B somefile.py

somefile.pycจะไม่ถูกสร้างขึ้น แต่จะไม่มี.pycการนำเข้าไฟล์สำหรับไฟล์อื่นด้วย

หากคุณมียูทิลิตี้บางอย่างmyutilและคุณไม่สามารถเปลี่ยนได้มันจะไม่ส่งผ่าน -B ไปยังตัวแปลของหลาม เพียงแค่เริ่มต้นโดยการตั้งค่าตัวแปรสภาพแวดล้อมPYTHONDONTWRITEBYTECODE:

PYTHONDONTWRITEBYTECODE=x myutil

4

ฉันมีกรณีทดสอบหลายชุดในชุดทดสอบและก่อนที่ฉันจะเรียกใช้ชุดทดสอบใน Mac Terminal อย่างนี้:

python LoginSuite.py

การรันคำสั่งด้วยวิธีนี้ไดเร็กทอรีของฉันจะถูกเติมด้วยไฟล์. pyc ฉันลองใช้วิธีการที่ระบุไว้ด้านล่างและแก้ไขปัญหา:

python -B LoginSuite.py

วิธีการนี้ใช้งานได้หากคุณนำเข้ากรณีทดสอบไปยังชุดทดสอบและเรียกใช้ชุดทดสอบในบรรทัดคำสั่ง


4

เริ่มต้นด้วยPython 3.8คุณสามารถใช้ตัวแปรสภาพแวดล้อมPYTHONPYCACHEPREFIXเพื่อกำหนดไดเรกทอรีแคชสำหรับ Python

จาก Python docs:

หากมีการตั้งค่าไว้ Python จะเขียนไฟล์. pyc ในแผนผังไดเร็กทอรีมิรเรอร์ที่พา ธ นี้แทนในไดเร็กทอรีpycacheภายในแผนผังซอร์ส นี่เทียบเท่ากับการระบุอ็อพชัน -X pycache_prefix = PATH

ตัวอย่าง

หากคุณเพิ่มบรรทัดต่อไปนี้./profileใน Linux:

export PYTHONPYCACHEPREFIX="$HOME/.cache/cpython/"

Python จะไม่สร้าง__pycache__ไดเรกทอรีที่น่ารำคาญในไดเรกทอรีโครงการของคุณ แต่มันจะใส่ไว้ในไดเรกทอรีทั้งหมด~/.cache/cpython/


2

คุณสามารถสร้างไดเรกทอรีที่โมดูลของคุณมีอยู่เป็นแบบอ่านอย่างเดียวสำหรับผู้ใช้ที่ Python interpreter ทำงานเป็น

ฉันไม่คิดว่าจะมีตัวเลือกที่หรูหรากว่านี้ PEP 304ดูเหมือนจะเป็นความพยายามที่จะแนะนำตัวเลือกที่ง่ายสำหรับเรื่องนี้ แต่ดูเหมือนว่าจะถูกทิ้งร้าง

ฉันคิดว่าอาจมีปัญหาอื่น ๆ ที่คุณพยายามแก้ไขซึ่งการปิดการใช้งาน. py [co] ดูเหมือนจะเป็นวิธีแก้ปัญหา


2

โซลูชันสำหรับipython 6.2.1 using python 3.5.2(ทดสอบบน Ubuntu 16.04 และ Windows 10):

Ipythonไม่เคารพ%env PYTHONDONTWRITEBYTECODE =1ถ้าตั้งอยู่ในipythoninterpretor ~/.ipython/profile-default/startup/00-startup.ipyหรือในระหว่างการเริ่มต้น แทนที่จะใช้สิ่งต่อไปนี้ในของคุณ~.ipython/profile-default/startup/00-startup.py

import sys
sys.dont_write_bytecode=True

0

เท่าที่ฉันรู้ python จะรวบรวมโมดูลทั้งหมดที่คุณ "นำเข้า" อย่างไรก็ตามไพ ธ อนจะไม่รวบรวมสคริปต์ไพ ธ อนที่ทำงานโดยใช้: "python script.py" (แต่จะรวบรวมโมดูลใด ๆ ที่สคริปต์นำเข้า)

คำถามจริงคือทำไมคุณไม่ต้องการให้ไพ ธ อนรวบรวมโมดูล? คุณอาจจะสามารถทำความสะอาดสิ่งเหล่านี้โดยอัตโนมัติหากพวกเขากำลังจะไป


ฉันพบว่ามี.pycไฟล์bytecode ค้างอยู่บ่อยครั้ง ด้วยเหตุผลบางอย่างเมื่อฉันเปลี่ยนคลาส / โมดูล.pycไฟล์จะไม่ได้รับการอัพเดต ดังนั้นเมื่อฉันนำเข้าไฟล์หลังจากเปลี่ยน.pyไฟล์มันจะยังคงใช้.pycไฟล์ซึ่งนำไปสู่ข้อผิดพลาด
alpha_989
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.