क्या मैं वैश्विक चर को परिभाषित करने के लिए __init__.py का उपयोग कर सकता हूं?


130

मैं एक स्थिरांक को परिभाषित करना चाहता हूं जो पैकेज के सभी सबमॉडल्स में उपलब्ध होना चाहिए। मैंने सोचा है कि __init__.pyरूट पैकेज की फ़ाइल में सबसे अच्छी जगह होगी । लेकिन मुझे नहीं पता कि यह कैसे करना है। मान लीजिए कि मेरे पास कुछ उप-पैकेज हैं और प्रत्येक में कई मॉड्यूल हैं। मैं इन मॉड्यूल से उस चर को कैसे एक्सेस कर सकता हूं?

बेशक, अगर यह पूरी तरह से गलत है, और एक बेहतर विकल्प है, तो मैं इसे जानना चाहूंगा।

जवाबों:


196

आपको उन्हें अंदर लाने में सक्षम होना चाहिए __init__.py। यह हर समय किया जाता है।

mypackage/__init__.py:

MY_CONSTANT = 42

mypackage/mymodule.py:

from mypackage import MY_CONSTANT
print "my constant is", MY_CONSTANT

फिर, आयात करें

>>> from mypackage import mymodule
my constant is 42

फिर भी, यदि आपके पास स्थिरांक हैं, तो उन्हें एक अलग मॉड्यूल (constants.py, config.py, ...) में रखना उचित (सर्वोत्तम प्रथाओं, शायद) होगा और फिर यदि आप उन्हें पैकेज नाम स्थान में चाहते हैं, तो आयात करें उन्हें।

mypackage/__init__.py:

from mypackage.constants import *

फिर भी, यह पैकेज मॉड्यूल के नाम स्थान में स्थिरांक को स्वचालित रूप से शामिल नहीं करता है। पैकेज में प्रत्येक मॉड्यूल को अभी भी mypackageया तो या उससे स्पष्ट रूप से स्थिरांक आयात करना होगा mypackage.constants


19
यह स्वीकृत उत्तर होना चाहिए था। यदि आप पायथन 2.5 या उच्चतर के साथ काम कर रहे हैं, तो आप एक स्पष्ट सापेक्ष आयात का उपयोग कर सकते हैं और साथ ही यहाँ वर्णित है : from . import MY_CONSTANT
ThatAintWorking

दूसरा तरीका केवल स्थिरांक के लिए काम नहीं करता है? from mypackage.constants import *की प्रतियां स्थापित करेंगे MY_CONSTANTबल्कि करने के लिए एक ही चर एक संदर्भ से हर submodule में
hardmooth

@ निर्मल: बिल्कुल नहीं। मानों को संदर्भ द्वारा कॉपी किया जाता है, इसलिए यदि आप MY_CONSTANTकिसी भी मॉड्यूल में म्यूट करना चाहते हैं, तो यह हर जगह म्यूट होगा। यदि आप MY_CONSTANTकिसी भी मॉड्यूल में फिर से असाइन करना चाहते हैं, तो यह केवल उस मॉड्यूल को प्रभावित करेगा। यदि आपका इरादा ऐसा है, तो आपको विशेषता द्वारा संदर्भ देना चाहिए, अर्थात mypackage.constants.MY_CONSTANT
जेसन आर। कोमब्स ने

7
उदाहरण के साथ एक पकड़ है, तो आप आयात है mymodule.pyमें __init__.pyसे पहले MY_CONSTANT = 42कि क्योंकि जब आयात विफल हो जाएगा mymodule.py MY_CONSTANTअभी तक निर्धारित नहीं किया गया। तो MY_CONSTANT = 42ऊपर जाने की जरूरत हैimport mymodule
5

चर कैसा है? यह स्थिरांक के बारे में पूछ रहा है, स्थिरांक नहीं। कैसे अजगर पैकेज के अंदर चर व्यवहार करता है? क्या होगा यदि पैकेज के अंदर चर को बदल दिया गया है?
टॉमसॉयर

31

तुम ऐसा नहीं कर सकते। आपको प्रत्येक व्यक्ति के मॉड्यूल के नामस्थान में अपने स्थिरांक का व्यापक रूप से आयात करना होगा। इसे प्राप्त करने का सबसे अच्छा तरीका है कि आप अपने स्थिरांक को एक "कॉन्फिगर" मॉड्यूल में परिभाषित करें और इसे हर जगह आयात करें जिसकी आपको आवश्यकता है:

# mypackage/config.py
MY_CONST = 17

# mypackage/main.py
from mypackage.config import *

हाँ, एक कॉन्फ़िगरेशन फ़ाइल वह है जो मैं चाहूंगा। मैंने बस सोचा था कि init .py एक अच्छी जगह होगी। आपका समाधान मानक अभ्यास जैसा लगता है। क्या यह?
आंद्रेई वजना II

1
अच्छी बात। मुझे इस बात का एहसास नहीं था कि सभी पैकेज मॉड्यूल के नाम स्थान में स्थिरांक स्वचालित रूप से रखा गया था।
जेसन आर। कोपब्स

लेकिन हर बार जब कोई स्क्रिप्ट config.py आयात करता है, तो अंदर कोड निष्पादित होता है। यदि आप config.py के अंदर कोड केवल एक बार चलाया जाना है तो आप क्या सलाह देंगे? मान लीजिए कि मैं config.py के अंदर settings.json फ़ाइल पढ़ रहा हूं और मैं हर बार जब मैं config.py आयात करता हूं तो इसे खोलना नहीं चाहता ()।
ऑग्विन

@ यूजीएस यह नहीं है कि पायथन कैसे काम करता है। प्रत्येक मॉड्यूल को केवल एक बार निष्पादित किया जाता है। जब इसे दूसरी बार आयात किया जाता है, तो मॉड्यूल पहले से ही कैश हो जाता है sys.modules
फर्डिनेंड बेयर

@FerdinandBeyer उफ़! मैं यह उल्लेख करना भूल गया कि मैं कई स्क्रिप्ट से config.py आयात कर रहा हूं और एक ही स्क्रिप्ट नहीं। मान लें कि a.py is configo आयात कर रहा है और b.py and b.py configy आयात कर रहा है। मैं सोच रहा था कि क्या यह संभव है कि config.py के अंदर कोड को केवल एक बार निष्पादित किया जाए।
औगिअन

2

आप कहीं से भी वैश्विक चर को परिभाषित कर सकते हैं, लेकिन यह वास्तव में एक बुरा विचार है। __builtin__मॉड्यूल को आयात करें और इस मॉड्यूल में विशेषताओं को संशोधित करें या जोड़ें, और अचानक आपके पास नए बिलिन स्थिरांक या फ़ंक्शन हैं। वास्तव में, जब मेरा एप्लिकेशन गेटटेक्स्ट स्थापित करता है, तो मुझे कुछ भी आयात किए बिना, मेरे सभी मॉड्यूल में _ () फ़ंक्शन मिलता है। तो यह संभव है, लेकिन केवल एप्लिकेशन-प्रकार की परियोजनाओं के लिए, पुन: प्रयोज्य पैकेज या मॉड्यूल के लिए नहीं।

और मुझे लगता है कि कोई भी इस अभ्यास की सिफारिश नहीं करेगा। एक नाम स्थान के साथ क्या गलत है? कहा आवेदन में संस्करण मॉड्यूल है, ताकि मेरे पास "वैश्विक" चर उपलब्ध हों जैसे version.VERSION, version.PACKAGE_NAMEआदि।


0

बस यह जोड़ना चाहते थे कि कॉन्स्टेंट को config.ini फ़ाइल का उपयोग करके नियोजित किया जा सकता है और configparser लाइब्रेरी का उपयोग करके स्क्रिप्ट में पार्स किया जा सकता है। इस तरह आप कई परिस्थितियों के लिए स्थिर हो सकते हैं। उदाहरण के लिए, यदि आपके पास दो अलग-अलग यूआरएल अनुरोधों के लिए पैरामीटर स्थिरांक थे, तो उन्हें केवल इस तरह लेबल करें:

mymodule/config.ini
[request0]
conn = 'admin@localhost'
pass = 'admin'
...

[request1]
conn = 'barney@localhost'
pass = 'dinosaur'
...

मुझे पायथन वेबसाइट पर प्रलेखन बहुत मददगार लगा। मुझे यकीन नहीं है कि पायथन 2 और 3 के बीच कोई अंतर है तो यहां दोनों के लिंक दिए गए हैं:

पायथन 3 के लिए: https://docs.python.org/3/library/configparser.html#module-configparser

पायथन 2 के लिए: https://docs.python.org/2/library/configparser.html#module-configparser

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.