__Init__.py में परिभाषित कक्षाएं कैसे आयात करें


105

मैं अपने स्वयं के उपयोग के लिए कुछ मॉड्यूल व्यवस्थित करने का प्रयास कर रहा हूं। मेरे पास कुछ इस तरह है:

lib/
  __init__.py
  settings.py
  foo/
    __init__.py
    someobject.py
  bar/
    __init__.py
    somethingelse.py

में lib/__init__.py, मैं कुछ वर्गों प्रयोग की जाने वाली परिभाषित करने के लिए अगर मैं lib आयात करना चाहते हैं। हालाँकि, मैं कक्षाओं को फ़ाइलों में अलग किए बिना इसे समझ नहीं सकता, और उन्हें आयात कर सकता हूं __init__.py

कहने के बजाय:

    lib/
      __init__.py
      settings.py
      helperclass.py
      foo/
        __init__.py
        someobject.py
      bar/
        __init__.py
        somethingelse.py

from lib.settings import Values
from lib.helperclass import Helper

मुझे कुछ इस तरह चाहिए:

    lib/
      __init__.py  #Helper defined in this file
      settings.py
      foo/
        __init__.py
        someobject.py
      bar/
        __init__.py
        somethingelse.py

from lib.settings import Values
from lib import Helper

क्या यह संभव है, या क्या मुझे कक्षा को किसी अन्य फ़ाइल में अलग करना है?

संपादित करें

ठीक है, अगर मैं किसी अन्य स्क्रिप्ट से आयात करता हूं, तो मैं हेल्पर वर्ग तक पहुंच सकता हूं। मैं सेटिंग्स-थ्रू से हेल्पर वर्ग तक कैसे पहुंच सकता हूं?

यहां उदाहरण इंट्रा-पैकेज संदर्भ का वर्णन करता है। मैं बोली "सबमॉड्यूल को अक्सर एक दूसरे को संदर्भित करने की आवश्यकता होती है"। मेरे मामले में, lib.settings.py


आपका आखिरी उदाहरण वहां काम करना चाहिए। क्या आप एक आयात देख रहे हैं? क्या आप विवरण पेस्ट कर सकते हैं?
जो होलोवे

जवाबों:


81
  1. ' lib/की मूल निर्देशिका में होना चाहिए sys.path

  2. आपका ' lib/__init__.py' इस तरह दिख सकता है:

    from . import settings # or just 'import settings' on old Python versions
    class Helper(object):
          pass

तब निम्न उदाहरण काम करना चाहिए:

from lib.settings import Values
from lib import Helper

प्रश्न के संपादित संस्करण का उत्तर दें:

__init__.pyपरिभाषित करता है कि आपका पैकेज बाहर से कैसा दिखता है। आप का उपयोग करने की आवश्यकता है Helperमें settings.pyतो परिभाषित Helperएक अलग फ़ाइल जैसे में, ' lib/helper.py'।

।
| `- import_submodule.py
    `- परिवाद
    | - __init__.py
    | - फू
    | | - __init__.py
    | `- someobject.py
    | - सहायक
    `- सेटिंग्स

2 निर्देशिका, 6 फाइलें

आदेश:

$ python import_submodule.py

आउटपुट:

settings
helper
Helper in lib.settings
someobject
Helper in lib.foo.someobject

# ./import_submodule.py
import fnmatch, os
from lib.settings import Values
from lib import Helper

print
for root, dirs, files in os.walk('.'):
    for f in fnmatch.filter(files, '*.py'):
        print "# %s/%s" % (os.path.basename(root), f)
        print open(os.path.join(root, f)).read()
        print


# lib/helper.py
print 'helper'
class Helper(object):
    def __init__(self, module_name):
        print "Helper in", module_name


# lib/settings.py
print "settings"
import helper

class Values(object):
    pass

helper.Helper(__name__)


# lib/__init__.py
#from __future__ import absolute_import
import settings, foo.someobject, helper

Helper = helper.Helper


# foo/someobject.py
print "someobject"
from .. import helper

helper.Helper(__name__)


# foo/__init__.py
import someobject

मैं अपने उदाहरण में settings.py फ़ाइल में हेल्पर वर्ग को कैसे आयात कर सकता हूं?
19

मुझे समझ में नहीं आता कि यह परिपत्र क्यों है। अगर सेटिंगहोम को हेल्पर की जरूरत है और कहते हैं कि foo.someobject.py को हेल्पर की जरूरत है, तो आप कहां सुझाव देंगे कि मैं इसे परिभाषित करूं?
स्कॉटलैंड

वाह, शब्द "सहायक" वास्तव में उस उदाहरण में ढीले अर्थ शुरू होता है। हालाँकि, आपने मुझे वह दिखाया है, जिसकी मुझे तलाश थी।
स्काउट

3
"__init__.py के लिए upvoted परिभाषित करता है कि आपका पैकेज बाहर से कैसा दिखता है।"
पेट्री

19

यदि lib/__init__.pyहेल्पर वर्ग को परिभाषित करता है तो सेटिंग्स में आप उपयोग कर सकते हैं:

from . import Helper

यह काम करता है क्योंकि वर्तमान निर्देशिका है, और सेटिंग मॉड्यूल के दृष्टिकोण से काम के पैकेज के लिए एक पर्याय के रूप में कार्य करता है। ध्यान दें कि हेल्पर को निर्यात करना आवश्यक नहीं है __all__

(विंडोज पर चल रहे अजगर 2.7.10 के साथ पुष्टि की गई।)


1
यह मेरे लिए ठीक काम कर रहा है, downvoters कृपया अपनी नाराजगी की व्याख्या करें?
योयो

8

आपने उन्हें __init__.py में डाला।

इसलिए परीक्षण / कक्षाओं के साथ:

class A(object): pass
class B(object): pass

... और परीक्षण / __ init__.py किया जा रहा है:

from classes import *

class Helper(object): pass

आप परीक्षण आयात कर सकते हैं और ए, बी और हेल्पर तक पहुंच सकते हैं

>>> import test
>>> test.A
<class 'test.classes.A'>
>>> test.B
<class 'test.classes.B'>
>>> test.Helper
<class 'test.Helper'>

आप कहां से आयात कर रहे हैं?
हारून मेंपा

मान लीजिए कि मैं lib / settings.py से हेल्पर आयात करना चाहता हूं?
स्कॉट

1
यह लगभग निश्चित रूप से एक परिपत्र आयात का परिणाम होगा (सेटिंग्स परीक्षण का आयात करेगी और परीक्षण सेटिंग्स आयात करेगा) ... जो आपके द्वारा वर्णित NameError का उत्पादन करेगा। यदि आप ऐसे सहायक चाहते हैं जो पैकेज के अंदर उपयोग किए जाते हैं, तो आपको एक आंतरिक मॉड्यूल को परिभाषित करना चाहिए जो आपके कोड का उपयोग करता है।
हारून मेनापा

1
Init .py के सहायक बाहरी उपयोगकर्ताओं के लिए आपके एपीआई को सरल बनाने के लिए होने चाहिए।
हारून मेनापा

1
अगर यह एपीआई का हिस्सा नहीं है, तो init .py वास्तव में इसके लिए जगह नहीं है। lib / internal.py या इससे अधिक बेहतर होगा (जिसका परिपत्र आयात की संभावना को कम करने का दोहरा उद्देश्य है)।
आरोन मेंपा


4

संपादित करें, क्योंकि मैंने सवाल गलत समझा:

बस Helperकक्षा में डाल दिया __init__.py। यह पूरी तरह से pythonic है। यह सिर्फ जावा जैसी भाषाओं से अजीब लगता है।


आपने गलत समझा। यदि संभव हो तो मैं helperClass.py फ़ाइल को समाप्त करना चाहता हूं।
स्कटम

रिचर्ड केवल एक ही नहीं है जो गलत समझा। आपका उदाहरण काम करना चाहिए। ट्रेसबैक क्या है?
ट्रॉय जे। फैरेल

खैर, फिर मैंने डॉक्स को सही ढंग से पढ़ा। इसलिए, अब मैंने सिर्फ एक परीक्षण का मामला बनाया है और यह ठीक काम करता है।
स्काउट

मेरे पैकेज में मेरे पास एक ही सेटअप है, लेकिन मुझे एक ImportError मिल रही है "जिसका नाम हेल्पर आयात नहीं कर सकता"
scottm

मुझे लगता है कि मेरी समस्या यह है कि मैं सेटिंग्डरो से हेल्पर वर्ग को आयात करने की कोशिश कर रहा हूं, मैं ऐसा कैसे कर सकता हूं?
19

2

हाँ यह संभव है। आप फ़ाइलों __all__में परिभाषित करना चाहते हैं __init__.py। यह उन मॉड्यूलों की एक सूची है जो आपके द्वारा किए जाने पर आयात किए जाएंगे

from lib import *

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