পাইথন 3 ব্যবহার করে জুপিটার নোটবুকের আপেক্ষিক আমদানির সাথে অন্য ডিরেক্টরিতে থাকা মডিউল থেকে স্থানীয় ফাংশন আমদানি করুন


127

আমার নিম্নলিখিত ডিরেক্টরিগুলির মতো ডিরেক্টরি কাঠামো রয়েছে

meta_project
    project1
        __init__.py
        lib
            module.py
            __init__.py
    notebook_folder
        notebook.jpynb

যখন কাজ notebook.jpynbযদি আমি একটি ফাংশন অ্যাক্সেস করতে একটি আপেক্ষিক আমদানি ব্যবহারের চেষ্টা function()মধ্যে module.pyসঙ্গে

from ..project1.lib.module import function

আমি নিম্নলিখিত ত্রুটি পেয়েছি:

SystemError                               Traceback (most recent call last)
<ipython-input-7-6393744d93ab> in <module>()
----> 1 from ..project1.lib.module import function

SystemError: Parent module '' not loaded, cannot perform relative import

আপেক্ষিক আমদানি ব্যবহার করে কি এটি পাওয়ার কোনও উপায় আছে?

দ্রষ্টব্য, নোটবুক সার্ভারটি meta_projectডিরেক্টরি স্তরে ইনস্ট্যান্ট করা হয় , সুতরাং সেই ফাইলগুলির মধ্যে তথ্যের অ্যাক্সেস থাকা উচিত।

নোট, এছাড়াও, যে অন্তত প্রাথমিকভাবে অভিহিত project1হিসাবে মডিউল হিসাবে ভাবা হয় নি এবং তাই কোন __init__.pyফাইল নেই, এটি কেবল একটি ফাইল-সিস্টেম ডিরেক্টরি হিসাবে বোঝানো হয়েছিল। যদি সমস্যার সমাধানের জন্য এটি মডিউল হিসাবে চিকিত্সা করা উচিত এবং একটি __init__.pyফাইল (এমনকি একটি ফাঁকাও) অন্তর্ভুক্ত রয়েছে তবে এটি ঠিক আছে, তবে সমস্যা সমাধানের জন্য এটি করা যথেষ্ট নয়।

আমি এই ডিরেক্টরিটি মেশিনগুলির মধ্যে ভাগ করি এবং আপেক্ষিক আমদানি আমাকে সর্বত্র একই কোড ব্যবহার করার অনুমতি দেয় এবং আমি প্রায়শই দ্রুত প্রোটোটাইপিংয়ের জন্য নোটবুক ব্যবহার করি, সুতরাং হ্যাকিংয়ের সাথে নিখুঁত পাথগুলিতে পরামর্শ দেওয়া সহায়ক হওয়ার সম্ভাবনা কম।


সম্পাদনা করুন: এটি পাইথন 3 এর তুলনামূলক আমদানির বিপরীতে , যা পাইথন 3-এ সাধারণভাবে এবং বিশেষত - কোনও প্যাকেজ ডিরেক্টরি থেকে স্ক্রিপ্ট চালানোর বিষয়ে আপেক্ষিক আমদানির কথা বলে। এটি একটি জুপিটার নোটবুকের মধ্যে কাজ করার সাথে অন্য কোনও ডিরেক্টরিতে স্থানীয় মডিউলে একটি ফাংশন কল করার চেষ্টা করে যা সাধারণ এবং বিশেষ উভয় দিকই রয়েছে।


1
__init__আপনার প্যাকেজ ডিরেক্টরিতে কোন ফাইল আছে?
আয়রন মুষ্টি

হ্যাঁ, libডিরেক্টরিতে।
এমপেসার

দয়া করে, আপনার প্রশ্নে এটি আপনার ডিরেক্টরি কাঠামোতে উল্লেখ করুন
আয়রন মুঠি

আমি আপনার প্রথম মন্তব্যটি দেখার সাথে সাথেই সম্পাদনাটি তৈরি করেছি :) :) এটি ধরার জন্য আপনাকে ধন্যবাদ।
এমপেসার

উত্তর:


173

আমি এই নোটবুকটিতে আপনার মতো প্রায় একই উদাহরণ পেয়েছি যেখানে আমি একটি ডিআরওয়াই পদ্ধতিতে একটি সংলগ্ন মডিউলটির ফাংশনটির ব্যবহার চিত্রিত করতে চেয়েছিলাম।

আমার সমাধানটি হ'ল নোটবুকটিতে এই জাতীয় স্নিপেট যুক্ত করে সেই অতিরিক্ত মডিউল আমদানির পথের পাইথনকে জানানো:

import os
import sys
module_path = os.path.abspath(os.path.join('..'))
if module_path not in sys.path:
    sys.path.append(module_path)

এটি আপনাকে মডিউল স্তরক্রম থেকে পছন্দসই ফাংশন আমদানি করতে দেয়:

from project1.lib.module import function
# use the function normally
function(...)

মনে রাখবেন যে আপনার কাছে ইতিমধ্যে প্রজেক্ট 1 / এবং লাইব / ফোল্ডার না থাকলে খালি __init__.pyফাইল যুক্ত করা দরকার।


6
এটি কম বা কম কোনও আপেক্ষিক অবস্থানের ব্যবহার করে প্যাকেজ আমদানি করতে সক্ষম হওয়ার সমস্যাটি সমাধান করে। আমি জানি যে মাথিয়াস বুসনিয়ার (@ ম্যাট অফ এসই) এবং যুভি পান্ডা (@ ইউইউআই) গিথুব / পিপিথন / আইপিনব বিকাশ করছে যা এটিকে আরও সরাসরি সমাধান করবে (উদাহরণস্বরূপ, তাদের প্যাকেজের পরে স্ট্যান্ডার্ড সিনট্যাক্স ব্যবহার করে আপেক্ষিক আমদানির অনুমতি দিয়ে আমদানি করা হয়)। আমি আপাতত আপনার উত্তরটি গ্রহণ করব, এবং যখন অন্যদের সমাধানের সমাধান সম্পূর্ণভাবে প্রস্তুত হয় আমি সম্ভবত এটি কীভাবে ব্যবহার করতে হয় সে সম্পর্কে একটি উত্তর লিখব, বা তাদের একজনকে এটি করার জন্য বলব।
এমপেসার

খালি ইশারা জন্য ধন্যবাদ Init .py আমি একটি পাইথন ব্রতী আছি এবং কষ্ট আমদানি করতে আমার ক্লাস পেয়ে চাপ ছিল। আমি মডিউল নোট ত্রুটি পাওয়া গেছে পেয়ে ছিল, খালি যোগ Init .py সমস্যা সংশোধন করা হয়েছে!
প্যাট গ্রেডি

5
খালি Init .py ফাইল আর পাইথন 3. প্রয়োজন হয়
CathyQian

অবগতির জন্য আছে: নোটবুক জন্য কোনো দর্শক নেই: nbviewer.jupyter.org/github/qPRC/qPRC/blob/master/notebook/...
thoroc

26

নোটবুকগুলিতে কাজ করার সময় সাবমোডিয়ুলগুলিতে কোড বিমূর্তকরণের সেরা অভ্যাসগুলির সন্ধান করতে এখানে এসেছিলেন। আমি নিশ্চিত নই যে এখানে একটি সেরা অনুশীলন রয়েছে। আমি এটি প্রস্তাব করছি।

প্রকল্পের শ্রেণিবিন্যাস যেমন:

├── ipynb
   ├── 20170609-Examine_Database_Requirements.ipynb
   └── 20170609-Initial_Database_Connection.ipynb
└── lib
    ├── __init__.py
    └── postgres.py

এবং থেকে 20170609-Initial_Database_Connection.ipynb:

    In [1]: cd ..

    In [2]: from lib.postgres import database_connection

এটি কাজ করে কারণ ডিফল্টরূপে Jupyter নোটবুক cdকমান্ডটি পার্স করতে পারে । দ্রষ্টব্য যে এটি পাইথন নোটবুক যাদু ব্যবহার করে না। এটি কেবল প্রিপেন্ডিং ছাড়াই কাজ করে %bash

বিবেচনা 100 আমি Docker মধ্যে কাজ করছি একটি ব্যবহার বাইরে যে 99 বার প্রকল্প Jupyter Docker চিত্র , নিম্নলিখিত পরিবর্তন হয় idempotent

    In [1]: cd /home/jovyan

    In [2]: from lib.postgres import database_connection

ধন্যবাদ। এই আপেক্ষিক আমদানির সীমাবদ্ধতা সত্যই ভয়ঙ্কর।
মাইকেল 9

আমিও পথটিতে chdirযুক্ত হওয়ার পরিবর্তে ব্যবহার করি , যেহেতু আমি উভয়ই মূল রেপো থেকে আমদানি করার পাশাপাশি সেখানে কয়েকটি ফাইলের সাথে ইন্টারফেসিং করতে আগ্রহী।
TheGrimmScientist

দুঃখের বিষয়, আমি পাইথনটিতে সবচেয়ে বেশি হ্যাক করি। তবুও, আমি আরও ভাল সমাধান খুঁজে পাচ্ছি না।
TheGrimmScientist

সাধারণ আদর্শশক্তির জন্য (একই কক্ষটি একাধিক বার চালানোর অনুমতি দেয় এবং একই ফলাফল পেতে পারে) if os.path.isdir('../lib/'): os.chdir('../lib'):; অথবা, আরও ভাল, ../lib/db/আপনার সাথে ব্যবহার করুন postgres.pyযাতে দুর্ঘটনাক্রমে অন্য একটি উচ্চতর ডিরেক্টরিতে একটি উচ্চ ডিরেক্টরিতে চিডির না হয় lib
মাইকেল

1
আমি দুর্ঘটনাক্রমে cd ..দু'বার সম্পাদন না করা পর্যন্ত এই সমাধানটি আমার পছন্দ like
minhle_r7

15

এখনও অবধি গ্রহণযোগ্য উত্তর আমার পক্ষে সবচেয়ে ভাল কাজ করেছে। যাইহোক, আমার উদ্বেগ সবসময়ই ছিল যে এমন একটি সম্ভাব্য পরিস্থিতি রয়েছে যেখানে আমি notebooksডিরেক্টরিটিকে উপ-ডিরেক্টরিতে পুনরায় বিক্রি করতে পারি , module_pathপ্রতিটি নোটবুকের মধ্যে পরিবর্তনটি প্রয়োজন । প্রয়োজনীয় মডিউলগুলি আমদানি করার জন্য আমি প্রতিটি নোটবুক ডিরেক্টরিতে পাইথন ফাইল যুক্ত করার সিদ্ধান্ত নিয়েছি।

সুতরাং, নিম্নলিখিত প্রকল্প কাঠামো থাকার:

project
|__notebooks
   |__explore
      |__ notebook1.ipynb
      |__ notebook2.ipynb
      |__ project_path.py
   |__ explain
       |__notebook1.ipynb
       |__project_path.py
|__lib
   |__ __init__.py
   |__ module.py

আমি project_path.pyপ্রতিটি নোটবুকের উপ-ডিরেক্টরিতে ( notebooks/exploreএবং notebooks/explain) ফাইল যুক্ত করেছি । এই ফাইলটিতে আপেক্ষিক আমদানির কোড রয়েছে (@ মেটকারমিট থেকে):

import sys
import os

module_path = os.path.abspath(os.path.join(os.pardir, os.pardir))
if module_path not in sys.path:
    sys.path.append(module_path)

এইভাবে, আমার কেবল project_path.pyফাইলের মধ্যেই আপেক্ষিক আমদানি করা দরকার , নোটবুকগুলিতে নয়। নোটবুক ফাইলগুলি তখন আমদানির project_pathআগে কেবল আমদানি করা দরকার lib। উদাহরণস্বরূপ 0.0-notebook.ipynb:

import project_path
import lib

এখানে সতর্কতাটি হ'ল আমদানিগুলিকে বিপরীত করা কাজ করবে না। এটা কাজ করে না:

import lib
import project_path

এইভাবে আমদানির সময় যত্ন নেওয়া উচিত।


3

আমি সবেমাত্র এই সুন্দর সমাধানটি পেয়েছি:

import sys; sys.path.insert(0, '..') # add parent folder path where lib folder is
import lib.store_load # store_load is a file on my library folder

আপনি কেবল এই ফাইলটির কিছু ফাংশন চান

from lib.store_load import your_function_name

পাইথন সংস্করণ> = = 3.3 আপনার ফোল্ডারে init.py ফাইলের দরকার নেই


3
আমি এটি খুব সহায়ক বলে মনে করি। আমি যুক্ত করব যে নিম্নলিখিত পরিবর্তনগুলি যুক্ত করা উচিত ->if ".." not in sys.path: ... sys.path.insert(0,"..")
ইয়াকভ ব্র্রেসার

2

আমি এই বিষয়টি নিজেই গবেষণা করছি এবং আমি উত্তর.প্যাটি লাইব্রেরি ব্যবহার করার পরামর্শ দিচ্ছি কারণ এটি বর্তমান কার্যকরী ডিরেক্টরি পরিবর্তনের জন্য একটি প্রসঙ্গ পরিচালক সরবরাহ করে।

আপনার তখন কিছু একটা আছে

import path
if path.Path('../lib').isdir():
    with path.Path('..'):
        import lib

যদিও, আপনি কেবল isdirবিবৃতি বাদ দিতে পারেন ।

এখানে যা ঘটছে তা অনুসরণ করা সহজ করার জন্য আমি মুদ্রণ বিবৃতি যুক্ত করব

import path
import pandas

print(path.Path.getcwd())
print(path.Path('../lib').isdir())
if path.Path('../lib').isdir():
    with path.Path('..'):
        print(path.Path.getcwd())
        import lib
        print('Success!')
print(path.Path.getcwd())

যা এই উদাহরণে ফলাফল (যেখানে lib রয়েছে /home/jovyan/shared/notebooks/by-team/data-vis/demos/lib):

/home/jovyan/shared/notebooks/by-team/data-vis/demos/custom-chart
/home/jovyan/shared/notebooks/by-team/data-vis/demos
/home/jovyan/shared/notebooks/by-team/data-vis/demos/custom-chart

যেহেতু সমাধানটি একটি প্রসঙ্গ ম্যানেজার ব্যবহার করে, আপনাকে আপনার পূর্ববর্তী ওয়ার্কিং ডিরেক্টরিতে ফিরে যাওয়ার নিশ্চয়তা দেওয়া হচ্ছে, আপনার কার্নেলটি কোষের আগে কী ছিল এবং আপনার গ্রন্থাগার কোডটি আমদানি করে কোনও ব্যতিক্রম ছুঁড়ে দেওয়া হোক না কেন।


এটি% অটোরলোডের সাথে একত্রে কাজ করবে না, যেহেতু পুনরায় লোডের সময় মডিউল পাথটি পাওয়া যাবে না
জোহানেস

1

এখানে আমার 2 সেন্ট:

আমদানি sys

মডিউল ফাইলটি যেখানে অবস্থিত সেখানে ম্যাপ করুন। আমার ক্ষেত্রে এটি ডেস্কটপ ছিল

sys.path.append ( '/ ব্যবহারকারীরা / জন / ডেস্কটপ')

হয় পুরো ম্যাপিং মডিউলটি আমদানি করুন তবে আপনাকে ম্যাপিংয়ের মতো শ্রেণীর মানচিত্রের জন্য। নোটেশনটি ব্যবহার করতে হবে hi শিপিং ()

আমদানি ম্যাপিং # ম্যাপিং.পি আমার মডিউল ফাইলের নাম

শিপইট = ম্যাপিং hip শিপমেন্ট () # শিপমেন্টটি ম্যাপিং মডিউলটিতে আমার যে শ্রেণীরটি ব্যবহার করা দরকার সেটির নাম

অথবা ম্যাপিং মডিউল থেকে নির্দিষ্ট শ্রেণিটি আমদানি করুন

ম্যাপিং আমদানি ম্যাপিং থেকে

শিপিট = চালান () # এখন আপনাকে। নোটেশন ব্যবহার করতে হবে না


0

আমি খুঁজে পেয়েছি যে পাইথন-ডোটেনভ এই সমস্যাটি বেশ কার্যকরভাবে সমাধান করতে সহায়তা করে। আপনার প্রকল্পের কাঠামোটি সামান্য পরিবর্তিত হয়ে শেষ হয়েছে, তবে আপনার নোটবুকের কোডটি নোটবুকগুলিতে কিছুটা সহজ এবং সামঞ্জস্যপূর্ণ।

আপনার প্রকল্পের জন্য, কিছুটা ইনস্টল করুন।

pipenv install python-dotenv

তারপরে, প্রকল্পটি এতে পরিবর্তন করে:

├── .env (this can be empty)
├── ipynb
   ├── 20170609-Examine_Database_Requirements.ipynb
   └── 20170609-Initial_Database_Connection.ipynb
└── lib
    ├── __init__.py
    └── postgres.py

এবং অবশেষে, আপনার আমদানি এতে পরিবর্তন করে:

import os
import sys

from dotenv import find_dotenv


sys.path.append(os.path.dirname(find_dotenv()))

এই প্যাকেজের জন্য একটি +1 হ'ল আপনার নোটবুকগুলি বেশ কয়েকটি ডিরেক্টরি গভীর হতে পারে। পাইথন-ডটেনভ একটি প্যারেন্ট ডিরেক্টরিতে নিকটতমটিকে খুঁজে পেতে এবং এটি ব্যবহার করবে। এই পদ্ধতির জন্য একটি +2 হ'ল জুপিটার শুরুতে .env ফাইল থেকে পরিবেশের ভেরিয়েবলগুলি লোড করবে। ডাবল ঘা।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.