एक अलग फ़ोल्डर से आयात करने के लिए अजगर नहीं मिल सकता


90

मैं एक सबफ़ोल्डर में एक मॉड्यूल आयात करने के लिए पायथन प्राप्त करने के लिए प्रतीत नहीं कर सकता। मुझे त्रुटि तब मिलती है जब मैं आयातित मॉड्यूल से कक्षा का एक उदाहरण बनाने की कोशिश करता हूं, लेकिन आयात स्वयं सफल होता है। यहाँ मेरी निर्देशिका संरचना है:

Server
    -server.py
    -Models
        --user.py

यहाँ server.py की सामग्री है:

from sys import path
from os import getcwd
path.append(getcwd() + "\\models") #Yes, i'm on windows
print path
import user

u=user.User() #error on this line

और user.py:

class User(Entity):
    using_options(tablename='users')

    username = Field(String(15))
    password = Field(String(64))
    email    = Field(String(50))
    status   = Field(Integer)
    created  = Field(DateTime)

त्रुटि यह है: विशेषता: 'मॉड्यूल' ऑब्जेक्ट में कोई विशेषता नहीं है 'उपयोगकर्ता'


1
क्या आप त्रुटि संदेश पेस्ट कर सकते हैं?
— हार्ले होल्कोम्बे

यदि user.py से, मैं server.py आयात करना चाहता हूं। मैं क्या करूं?
— चंद्र कंठ

जवाबों:


142

मेरा मानना ​​है कि आपको __init__.pyमॉडल निर्देशिका में एक फ़ाइल बनाने की आवश्यकता है ताकि अजगर इसे एक मॉड्यूल के रूप में मानता है।

तो आप कर सकते हैं:

from Models.user import User

आप इसमें कोड शामिल कर सकते हैं __init__.py(उदाहरण के लिए प्रारंभिक कोड जिसे कुछ अलग वर्गों की आवश्यकता है) या इसे खाली छोड़ दें। लेकिन यह वहाँ होना चाहिए।


2
धन्यवाद, मैंने इससे पहले पैकेज के बारे में कभी नहीं सुना था।
— रियुगी

1
दरअसल, जब पायथन आयात करते हैं तो blah.py और blah / __ init__.py बिल्कुल वैसा ही व्यवहार करता है।
— पी।

2
यह स्पष्ट नहीं था ... और मैं खुद से कहता हूं: RTFM FMF
— Alexander.Iljushkin

1
ध्यान दें कि यदि आप किसी अन्य निर्देशिका से server.py चला रहे हैं तो यह काम नहीं करेगा।
— kchoi

1
क्या होगा अगर server.py दूसरे फ़ोल्डर में है?
— 17

24

आपको सबफ़ोल्डर __init__.pyपर बनाना होगा Models। फ़ाइल खाली हो सकती है। यह एक पैकेज को परिभाषित करता है।

तो आप कर सकते हैं:

from Models.user import User

अजगर ट्यूटोरियल में इसके बारे में सभी पढ़ें, यहां ।

यहां अजगर परियोजनाओं के फाइल संगठन के बारे में एक अच्छा लेख भी है ।


यदि फ़ाइल खाली नहीं है तो क्या होगा?
— डार्कजैग

12

उपयोगकर्ता आयात करें

इस लाइन पर u = user.User () #error

ऊपर उल्लिखित __in__ की कमी के कारण, आप एक आयात की उम्मीद करेंगे जो समस्या को स्पष्ट करेगा।

आपको एक नहीं मिलता क्योंकि मानक पुस्तकालय में 'उपयोगकर्ता' भी एक मौजूदा मॉड्यूल है। आपका आयात विवरण उस एक को पकड़ लेता है और उसके अंदर उपयोगकर्ता वर्ग को खोजने की कोशिश करता है; यह मौजूद नहीं है और केवल तभी आपको त्रुटि मिलती है।

आम तौर पर अपने आयात को निरपेक्ष बनाना एक अच्छा विचार है:

import Server.Models.user

इस तरह की अस्पष्टता से बचने के लिए। वास्तव में पायथन 2.7 'आयात उपयोगकर्ता' वर्तमान मॉड्यूल के सापेक्ष बिल्कुल भी नहीं दिखेगा।

यदि आप वास्तव में सापेक्ष आयात चाहते हैं, तो आप उन्हें स्पष्ट रूप से अजगर 2.5 और कुछ बदसूरत सिंटैक्स का उपयोग कर सकते हैं:

from .user import User

9

मूल फ़ोल्डर संरचना पर स्थित मॉड्यूल को आयात करने का सही तरीका, जब आपके पास मानक पैकेज संरचना नहीं है, यह है:

import os, sys
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(CURRENT_DIR))

(आप अंतिम दो पंक्तियों को मिला सकते हैं लेकिन इस तरीके को समझना आसान है)।

यह समाधान क्रॉस-प्लेटफ़ॉर्म है और अन्य परिस्थितियों में संशोधित नहीं करने के लिए पर्याप्त सामान्य है।


7

आपको __init__.py याद आ रहा है। पायथन ट्यूटोरियल से:

__Init__.py फ़ाइलों को पैकेज युक्त निर्देशिकाओं का इलाज करने के लिए पायथन की आवश्यकता होती है; यह एक सामान्य नाम के साथ निर्देशिकाओं को रोकने के लिए किया जाता है, जैसे कि स्ट्रिंग, अनजाने में वैध मॉड्यूल छिपाते हैं जो बाद में मॉड्यूल खोज पथ पर होते हैं। सबसे सरल स्थिति में, __init__.py केवल एक खाली फ़ाइल हो सकती है, लेकिन यह पैकेज के लिए इनिशियलाइज़ेशन कोड को निष्पादित कर सकता है या बाद में वर्णित __all__ वैरिएबल को सेट कर सकता है।

अपने मॉडल निर्देशिका में __init__.py नामक एक खाली फ़ाइल रखो, और सभी को सुनहरा होना चाहिए।


1

आप कैसे लिखते हैं os.path.dirname?

import os, sys
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(CURRENT_DIR))

0

मेरा पसंदीदा तरीका है कि प्रत्येक निर्देशिका पर __init__.py है जिसमें ऐसे मॉड्यूल हैं जो अन्य मॉड्यूल द्वारा उपयोग किए जाते हैं, और प्रवेश बिंदु में, नीचे के रूप में sys.path को ओवरराइड करें:

def get_path(ss):
  return os.path.join(os.path.dirname(__file__), ss)
sys.path += [
  get_path('Server'), 
  get_path('Models')
]

यह फ़ाइलों को आयात करने के लिए दृश्यमान निर्देशिकाओं में बनाता है, और मैं उपयोगकर्ता को Server.py से आयात कर सकता हूं।


0

ऊपर इन योगदानकर्ताओं द्वारा दिए गए उत्तरों के माध्यम से जाने के बाद - Zorglub29, Tom, Mark, Aaron McMillin, lucasamaral, JoeyZhao, Kjeld Flarup, Procyclinsur, martin.zaenker, tooty44 और इस मुद्दे को डीबग करना कि मुझे एक अलग उपयोग मामले के कारण पता चला है। जिससे मैं इस मुद्दे का सामना कर रहा था। इसलिए किसी के संदर्भ के लिए नीचे मेरी टिप्पणियों को जोड़ना।

मेरे कोड में मैंने कक्षाओं का चक्रीय आयात किया था। उदाहरण के लिए:

src
 |-- utilities.py (has Utilities class that uses Event class)  
 |-- consume_utilities.py (has Event class that uses Utilities class)
 |-- tests
      |-- test_consume_utilities.py (executes test cases that involves Event class)

जब मुझे python -m pytest परीक्षण / test_utilities.py पर परीक्षण करने के लिए UT_ निष्पादित करने के लिए प्रयास करने में त्रुटि हुई, तो मुझे निम्न त्रुटि मिली।

ImportError while importing test module '/Users/.../src/tests/test_utilities.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_utilities.py:1: in <module>
    from utilities import Utilities
...
...
E   ImportError: cannot import name 'Utilities'

जिस तरह से मैंने त्रुटि को हल किया वह चक्रीय आयात वर्ग में कार्यक्षमता को स्थानांतरित करने के लिए मेरे कोड को फिर से फैक्टरिंग करके था ताकि मैं कक्षाओं के चक्रीय आयात को हटा सकूं।

ध्यान दें, मेरे पास __init__.pyमेरे ' src ' फ़ोल्डर के साथ-साथ ' परीक्षण ' फ़ोल्डर में फ़ाइल है और फिर भी' EEEEror 'से छुटकारा पाने में सक्षम है सिर्फ फिर से बाँटे कोड द्वारा'।

निम्नलिखित स्टैकओवरफ़्लो लिंक पायथन में परिपत्र निर्भरता पर बहुत अधिक विवरण प्रदान करता है ।

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