কেন "আমদানি *" খারাপ?


152

import *পাইথনে ব্যবহার না করার পরামর্শ দেওয়া হচ্ছে ।

কেউ কি দয়া করে এর কারণটি ভাগ করে নিতে পারেন, যাতে আমি পরের বার এটি করা এড়াতে পারি?


3
ডুপ্লিকেট: stackoverflow.com/questions/2360724/...
S.Lott

2
এটি নির্ভর করে যদি আপনি স্ক্রিপ্টিং করছেন বা আপনার কোডটি পুনঃব্যবহার করা প্রয়োজন লিখছেন। এটি কখনও কখনও কোডের মান অগ্রাহ্য করার জন্য অর্থ প্রদান করে। আপনার যদি নামকরণের কনভেনশন থাকে যা পরিষ্কার করে দেয় যে জিনিসগুলি কোথা থেকে এসেছে "" আমদানি * "ও ঠিকঠাক হতে পারে। উদাহরণস্বরূপ "বিড়াল আমদানি থেকে *; তাবিবিটি; মেইনকনগ্যাট; ক্যালিকোক্যাট;"
gatoatigrado

3
import *পাইথন 2 বা 3 এ প্রথম স্থানে আমার জন্য কাজ করে না
joshreejones

1
এটা কি তোমার প্রশ্নের উত্তর? "আমদানি *" আমদানি ঠিক কী করে?
এএমসি

উত্তর:


222
  • কারণ এটি আপনার নেমস্পেসে প্রচুর পরিমাণে জিনিস রাখে (পূর্ববর্তী আমদানি থেকে অন্য কোনও বিষয়কে ছায়া দিতে পারে এবং আপনি এটি সম্পর্কে জানতে পারবেন না)।

  • কারণ আপনি জানেন না ঠিক কীটি আমদানি করা হয় এবং সহজেই কোন মডিউল থেকে কোনও নির্দিষ্ট জিনিস আমদানি করা হত তা খুঁজে পাওয়া যায় না (পঠনযোগ্যতা)।

  • কারণ আপনি দুর্দান্ত pyflakesকোডগুলি আপনার কোডটিতে ত্রুটিগুলি স্থির রাখতে পছন্দ করতে পারবেন না ।


2
হ্যাঁ, আমি আমার কাজটিতে সত্যিই ঘৃণা করি যখন কেউ * আমদানি ব্যবহার করে, কারণ তখন আমি কেবল পাইফ্লেক চালাতে পারি না এবং খুশি হতে পারি না, তবে সেই আমদানিগুলি মেরামত করতে হয়। যদিও এটি খুব সুন্দর, যে পাইফ্লেক্সের সাহায্যে আমাকে :
গ্রাস্কজি

6
একটি কংক্রিট উদাহরণ হিসাবে, NumPy অনেক ব্যবহারকারীদের দ্বারা কামড় হয়েছে numpy.anyছায়া anyযখন তারা from numpy import *বা "সহায়ক" টুল তাদের জন্য এটা আছে।
ব্যবহারকারী 2357112 মনিকা

1
একই কারণে আইপিথনের জন্য --yplav স্যুইচ ব্যবহার করা উচিত?
টিমজেব

6
একটি ঝুঁকি আমি এই পড়ার আগে কখনও ভাবি নি চাই হাইলাইট করতে ( "পূর্ববর্তী আমদানি থেকে কিছু অন্যান্য বস্তু ছায়া পারে"): import *তোলে অর্ডার এর importবিবৃতি উল্লেখযোগ্য ... এমনকি মান গ্রন্থাগার মডিউল যা স্বাভাবিকভাবে আমদানি অর্ডার যত্ন সম্পর্কে না জন্য । আপনার importবিবৃতিগুলিকে বর্ণমালা করার মতো নিরীহ কিছু আপনার স্ক্রিপ্টটি ভেঙে দিতে পারে যখন আমদানি যুদ্ধের একটি প্রাক্তন দুর্ঘটনা একমাত্র বেঁচে যায়। (যদিও আপনার স্ক্রিপ্টটি এখন কাজ করে এবং কখনই পরিবর্তন হয় না, যদি আমদানি করা মডিউলটি আপনার উপর নির্ভর করে এমন একটি ব্যক্তিকে প্রতিস্থাপন করে এমন একটি নতুন নাম পরিচয় করিয়ে দেয় তবে হঠাৎ এটি ব্যর্থ হতে পারে))
কেভিন জে চেস

48

পাইথনের জেন অনুসারে :

সুস্পষ্ট বর্ণিত চেয়ে ভাল।

... নিশ্চয়ই তর্ক করতে পারছিনা?


28
আসলে, আপনি যে সঙ্গে তর্ক করতে পারেন । এটি সম্পূর্ণরূপে অসঙ্গত, প্রদত্ত যে আপনি পাইথনগুলিতে স্পষ্টভাবে ভেরিয়েবলগুলি ঘোষণা করেন না, আপনি তাদের অর্পণ করার পরে তারা কেবল অস্তিত্বের মধ্যে চলে যায়।
কনরাড রুডলফ

7
@ গ্রুসস্কি: ভেরিয়েবল ঘোষণা করা কীসের থেকে অপ্রয়োজনীয় ? বরাদ্দ করা? না, এটি দুটি পৃথক ধারণা এবং কোনও কিছু ঘোষণা করা খুব স্বতন্ত্র এবং গুরুত্বপূর্ণ তথ্য দেয়। যাইহোক, প্রতিচ্ছবি সর্বদা অপ্রয়োজনীয়তার সাথে কিছুটা যুক্ত থাকে, তারা একই মুদ্রার দুটি মুখ।
কনরাড রুডল্ফ

3
@ ক্রিস ঠিক আছে, তবে এটি আমার বক্তব্য ছিল না। আমার বক্তব্যটি হ'ল সুস্পষ্টভাবে কোনও পরিবর্তনশীলকে ত্রুটির দিকে পরিচালিত করতে ব্যর্থতা। আপনি বলছেন যে "[ঘোষণা] ব্যতীত অ্যাসাইনমেন্ট অসম্ভব"। তবে এটি ভুল, আমার পুরো বক্তব্যটি হল পাইথন দুর্ভাগ্যক্রমে ঠিক এটি সম্ভব করে তুলেছে।
কনরাড রুডল্ফ

3
@ ক্রিসস ঘোষণার মাধ্যমে সংকলককে দেওয়া তথ্যের আরও একটি অংশ হ'ল সত্য যে আপনি সত্যই একটি নতুন পরিবর্তনশীল ঘোষণার ইচ্ছা করে। এটি টাইপ সিস্টেমের জন্য তথ্যগুলির একটি গুরুত্বপূর্ণ অংশ। আপনি বলছেন যে আধুনিক আইডিইগুলি ভুল টাইপিং সমস্যার সমাধান করে তবে এটি কেবল ভুল, এবং বাস্তবে এটি স্ট্যাটিকালি সংকলিত ভাষাগুলিতে একটি যথেষ্ট সমস্যা, যার কারণে পার্ল যুক্ত হয়েছে use strict(জাভাস্ক্রিপ্ট var)। একদিকে যেমন পাইথন অবশ্যই নিরাকার নয় (এটি আসলে দৃ strongly়ভাবে টাইপ করা হয়)। যাই হোক, এমনকি যদি আপনি সঠিক ছিলেন, এই এখনও Python- র জেন বিপরীত হবে, এই উত্তরে উদাহৃত।
কনরাড রুডল্ফ

3
@ ক্রিসস আপনার এটির ভুল আছে: একই চলক নামটি পুনরায় ব্যবহার করা কোনও সমস্যা নয় the একই ভেরিয়েবলটির পুনরায় ব্যবহার করা হ'ল (অর্থাত্ একই ক্ষেত্রের একই নাম)। সুস্পষ্ট ঘোষণাগুলি ঠিক এই ভুলটিকে আটকাতে পারে (এবং অন্যেরা, সাধারণ ভুল টাইপিংয়ের উপর ভিত্তি করে, যা আমি বলেছি যে এটি আসলে একটি অত্যন্ত সাধারণ এবং সময়সাপেক্ষ সমস্যা, যদিও আপনি ঠিক বলেছেন যে পার্লের মতো সমস্যাটি আরও বড় is ভাষা)। এবং আমি যে বৈপরীত্যের পরিচয় দিয়েছি তা হ'ল জেনের স্পষ্টবাদীতার প্রয়োজনীয়তা, যা এখানে উইন্ডো থেকে শারীরিকভাবে ফেলে দেওয়া হয়।
কনরাড রুডল্ফ

40

আপনি **locals()ফাংশনগুলিতে পাস করেন না , তাই না?

যেহেতু পাইথন একটি "অন্তর্ভুক্ত", বিবৃতি অভাব আছে, এবংself পরামিতি স্পষ্ট হয়, এবং scoping নিয়ম বেশ সহজ, এটি সাধারণত একটি পরিবর্তনশীল একটি আঙুল নির্দেশ করুন এবং বলতে যেখানে যে বস্তুর থেকে আসে খুব সহজ - অন্যান্য মডিউল পড়া ছাড়া এবং কোনো ধরনের ছাড়া আইডিই (যা যাইহোক অন্তর্নিবেশনের পথে সীমাবদ্ধ, আসলে ভাষাটি খুব গতিশীল)

import *বিরতি যে সব।

এছাড়াও, এটিতে বাগগুলি লুকানোর একটি দৃ possibility় সম্ভাবনা রয়েছে।

import os, sys, foo, sqlalchemy, mystuff
from bar import *

এখন, যদি বার মডিউলটিতে " os", " mystuff" ইত্যাদি ... বৈশিষ্ট্য থাকে তবে তারা সুস্পষ্টভাবে আমদানি করাগুলিকে ওভাররাইড করে এবং সম্ভবত খুব আলাদা জিনিসগুলিতে নির্দেশ করে। __all__বারে সংজ্ঞায়িত করা প্রায়শই বুদ্ধিমান - এটি সূচিত করে যা আমদানি করা হবে - তবে বার মডিউলটি পড়ার এবং পার্সিং না করে এবং এর আমদানিগুলি অনুসরণ করে অবজেক্টগুলি কোথা থেকে আসে তা সনাক্ত করা শক্ত । এর একটি নেটওয়ার্ক import *প্রথম জিনিস আমি ঠিক যখন আমি একটি প্রকল্পের মালিকানা নিতে হয়।

আমাকে ভুল বুঝবেন না: যদি import *অনুপস্থিত থাকতেন তবে আমি তা পেয়ে চিৎকার করব। তবে এটি সাবধানে ব্যবহার করতে হবে। একটি ভাল ব্যবহারের ক্ষেত্রে হ'ল অন্য মডিউলের উপরে একটি ফ্যাকাস ইন্টারফেস সরবরাহ করা। তেমনি শর্তসাপেক্ষ আমদানি বিবৃতি ব্যবহার, বা ফাংশন / শ্রেণীর নেমস্পেসের অভ্যন্তরে আমদানি করার জন্য কিছুটা শৃঙ্খলা দরকার।

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

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


6
পাইথন 2.x করে একটি "অন্তর্ভুক্ত", বিবৃতি আছে। এটি বলা হয় execfile()। ভাগ্যক্রমে, এটি খুব কমই ব্যবহৃত হয় এবং 3.x এ চলে যায়।
সোভেন মারনাচ

**vars()যদি ডাকা ফাংশন অন্য কোনও ফাইলে থাকে তবে গ্লোবালগুলি কীভাবে অন্তর্ভুক্ত করবেন? : পি
সলোমন উকো

16

from ... import *একটি ইন্টারেক্টিভ সেশনে করা ঠিক আছে ।


কিভাবে একটি doctestস্ট্রিং ভিতরে ? import *এই ক্ষেত্রে "স্যান্ডবক্স" এর অভ্যন্তরে কি ব্যাখ্যা করা যায়? ধন্যবাদ।
প্যাট্রিকটি

16

কারণ আপনি নাম স্থান দূষিত করছেন। আপনি নিজের নামস্থানে সমস্ত ফাংশন এবং ক্লাসগুলি আমদানি করবেন, যা আপনি নিজের দ্বারা সংজ্ঞায়িত ফাংশনগুলির সাথে সংঘর্ষে থাকতে পারে।

তদুপরি, আমি মনে করি রক্ষণাবেক্ষণের জন্য একটি যোগ্য নাম ব্যবহার করা আরও স্পষ্ট; আপনি কোড লাইনে নিজেই দেখতে পাবেন যেখানে কোনও ফাংশন আসে, তাই আপনি ডকগুলি আরও সহজেই পরীক্ষা করে দেখতে পারেন।

মডিউল foo এ:

def myFunc():
    print 1

আপনার কোডে:

from foo import *

def doThis():
    myFunc() # Which myFunc is called?

def myFunc():
    print 2


9

বলুন যে foo নামক একটি মডিউলে আপনার নীচের কোড রয়েছে:

import ElementTree as etree

এবং তারপরে আপনার নিজের মডিউলে:

from lxml import etree
from foo import *

আপনার এখন একটি হার্ড-টু-ডিবাগ মডিউল রয়েছে যা দেখে মনে হচ্ছে এটিতে lxML এর এট্রি রয়েছে তবে এর পরিবর্তে এলিমেন্ট্রি রয়েছে T


7

এগুলি সব ভাল উত্তর। আমি যুক্ত করতে যাচ্ছি যখন পাইথনে কোড করার জন্য নতুন লোকদের শেখাচ্ছি, তখন ডিল করছেimport * করা খুব কঠিন। আপনি বা তারা কোডটি না লিখলেও এটি এখনও হোঁচট খাচ্ছে।

আমি বাচ্চাদের (প্রায় 8 বছর বয়সী) পাইথনে মিনক্রাফ্ট চালাতে প্রোগ্রাম করতে শিখি। আমি তাদের ( অ্যাটম সম্পাদক ) এর সাথে কাজ করার জন্য এবং একটি রিপিএল চালিত বিকাশ ( বিপিথনের মাধ্যমে ) শেখানোর জন্য একটি সহায়ক কোডিং পরিবেশ দিতে চাই । পরমাণুতে আমি দেখতে পাই যে ইঙ্গিতগুলি / সমাপ্তি ঠিক তেমন কার্যকরভাবে বিপিথনের মতো কার্যকরভাবে কাজ করে। ভাগ্যক্রমে, অন্যান্য অন্যান্য পরিসংখ্যান বিশ্লেষণ সরঞ্জামগুলির মতো, এটম দ্বারা বোকা নয় import *

যাইহোক, এই উদাহরণটি নেওয়া যাক ... এই মোড়কগুলিতে তারা ব্লকের এই তালিকাfrom local_module import * সহ একটি গুচ্ছ মডিউল । নেমস্পেসের সংঘর্ষের ঝুঁকি উপেক্ষা করা যাক। এমনটি করে তারা ব্লক কিছু অস্পষ্ট ধরনের এই সমগ্র তালিকা তৈরি আপনাকে জানতে হবে কি পাওয়া যায় এ বর্ণন যেতে হবে যে। যদি তারা পরিবর্তে এটি ব্যবহার করে থাকে তবে আপনি টাইপ করতে পারতেন এবং তারপরে একটি স্ব-পরিপূর্ণ তালিকা পপ আপ হয়ে যায়। from mcpi.block import *from mcpi import blockwalls = block.Atom.io স্ক্রিনশট


6

লোকেরা এখানে দেওয়া বৈধ পয়েন্টগুলি বোঝে। তবে, আমার একটি যুক্তি রয়েছে যে, "স্টার আমদানি" সর্বদা খারাপ অভ্যাস নাও হতে পারে:

  • যখন আমি আমার কোডটি এমনভাবে গঠন করতে চাই যাতে সমস্ত ধ্রুবকগুলি মডিউলটিতে ডাকা হয় const.py :
    • যদি আমি এটি করি import const, তবে প্রতিটি ধ্রুবকটির জন্য, আমাকে এটি হিসাবে উল্লেখ করতে হবে const.SOMETHING, যা সম্ভবত সবচেয়ে সুবিধাজনক উপায় নয়।
    • যদি আমি এটি করি from const import SOMETHING_A, SOMETHING_B ...তবে স্পষ্টতই এটি বেশ ভার্জোজ এবং স্ট্রাকচারিংয়ের উদ্দেশ্যকে পরাস্ত করে।
    • এইভাবে আমি এই ক্ষেত্রে অনুভব করি, from const import *এটি করা আরও ভাল পছন্দ হতে পারে।

4

এটি দুটি কারণে খুব খারাপ অভ্যাস:

  1. কোড পাঠযোগ্যতা
  2. ভেরিয়েবল / ফাংশন ইত্যাদিকে ওভাররাইড করার ঝুঁকি

জন্য পয়েন্ট 1 : আসুন এই একটি উদাহরণ দেখুন:

from module1 import *
from module2 import *
from module3 import *

a = b + c - d

এখানে, কোড প্রেক্ষণ উপর কেউ ধারণা যা মডিউল থেকে সংক্রান্ত পাবেন b, cএবংd আসলে জন্যে।

অন্যদিকে, আপনি যদি এটি করেন তবে:

#                   v  v  will know that these are from module1
from module1 import b, c   # way 1
import module2             # way 2

a = b + c - module2.d
#            ^ will know it is from module2

এটি আপনার পক্ষে অনেক পরিস্কার এবং আপনার দলে যোগদান করা নতুন ব্যক্তিটির সম্পর্কে আরও ভাল ধারণা থাকবে।

জন্য বিন্দু 2 : উভয় বলে module1এবং module2যেমন পরিবর্তনশীল আছে b। যখন আমি করি:

from module1 import *
from module2 import *

print b  # will print the value from module2

এখানে থেকে মানটি module1হারিয়ে গেছে। কোডটি bঘোষণা করা সত্ত্বেও কেন কোডটি কাজ করছে না তা ডিবাগ করা কঠিন হবেmodule1 এবং আমার কোডটি ব্যবহার করার প্রত্যাশা করে কোডটি লিখেছিmodule1.b

বিভিন্ন মডিউলে আপনার যদি একই ভেরিয়েবল থাকে এবং আপনি পুরো মডিউলটি আমদানি করতে না চান তবে আপনি এটি করতেও পারেন:

from module1 import b as mod1b
from module2 import b as mod2b

2

পরীক্ষা হিসাবে, আমি 2 এবং এফ বি দ্বারা একটি মডিউল টেস্ট.পি তৈরি করেছি, যা যথাক্রমে "এ 1" এবং "বি 1" মুদ্রণ করে। এর সাথে test.py আমদানি করার পরে:

import test

। । । আমি 2 টি ফাংশনটি টেস্ট.এ () এবং টেস্ট.বি () হিসাবে চালাতে পারি, এবং "পরীক্ষা" নামস্থানটিতে একটি মডিউল হিসাবে প্রদর্শিত হয় , তাই আমি যদি টেস্ট.পি সম্পাদনা করি তবে আমি এটিকে পুনরায় লোড করতে পারি:

import importlib
importlib.reload(test)

তবে আমি যদি নিম্নলিখিতগুলি করি:

from test import *

নেমস্পেসে "পরীক্ষা" সম্পর্কিত কোনও রেফারেন্স নেই, সুতরাং সম্পাদনার পরে এটিকে পুনরায় লোড করার কোনও উপায় নেই (যতদূর আমি বলতে পারি), যা ইন্টারেক্টিভ সেশনে সমস্যা। যেখানে নিম্নলিখিত দুটির মধ্যে:

import test
import test as tt

নেমস্পেসে মডিউল নাম হিসাবে "পরীক্ষা" বা "টিটি" (যথাক্রমে) যুক্ত করবে, যা পুনরায় লোডিংয়ের অনুমতি দেবে।

যদি আমি করি:

from test import *

নাম "এ" এবং "বি" নামগুলি কার্যক্ষেত্র হিসাবে নেমস্পেসে প্রদর্শিত হয় । যদি আমি টেস্ট.পি সম্পাদনা করি এবং উপরের কমান্ডটি পুনরায় করি তবে ফাংশনগুলির পরিবর্তিত সংস্করণগুলি পুনরায় লোড হবে না।

এবং নিম্নলিখিত কমান্ড একটি ত্রুটি বার্তা elicits।

importlib.reload(test)    # Error - name 'test' is not defined

যদি কেউ জানেন যে "মডিউল আমদানি *" দিয়ে লোড করা কোনও মডিউল কীভাবে পুনরায় লোড করতে হয় তবে দয়া করে পোস্ট করুন। অন্যথায়, ফর্মটি এড়ানোর এটি অন্য কারণ হতে পারে:

from module import *

2

ডক্সে যেমন পরামর্শ দেওয়া হয়েছে, আপনার (প্রায়) কখনই ব্যবহার করা উচিত নয় import * উত্পাদন কোড ।

মডিউল* থেকে আমদানি করা খারাপ, প্যাকেজ থেকে * আমদানি করা আরও খারাপ। ডিফল্টরূপে, প্যাকেজের পূর্বনির্ধারিত যে কোনও সাবমডিউল সহ প্যাকেজটির দ্বারা নির্ধারিত যেকোন নাম আমদানি করেfrom package import *__init__.pyimport বিবৃতি ।

তবে, যদি কোনও প্যাকেজের __init__.pyকোড নামের তালিকাটি সংজ্ঞায়িত করে __all__, তবে সাবমডিউলের নামের তালিকা হিসাবে নেওয়া হবে from package import *যা সম্মুখীন হওয়ার পরে আমদানি করা উচিত ।

এই উদাহরণটি বিবেচনা করুন (ধরে নিলেন এমন কোনও __all__সংজ্ঞায়িত নেই sound/effects/__init__.py):

# anywhere in the code before import *
import sound.effects.echo
import sound.effects.surround

# in your module
from sound.effects import *

সর্বশেষ বিবৃতিটি বর্তমান নামস্থানতে (সম্ভবত পূর্ববর্তী সংজ্ঞাগুলি ওভাররাইড করা) এগুলি echoএবং surroundমডিউলগুলি আমদানি করবে কারণ বিবৃতি কার্যকর করা sound.effectsহলে প্যাকেজটিতে সেগুলি সংজ্ঞায়িত importকরা হয়।

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