ফাইলগুলির মধ্যে গ্লোবাল ভেরিয়েবল ব্যবহার করছেন?


207

গ্লোবাল ভেরিয়েবলগুলি কীভাবে কাজ করে সে সম্পর্কে আমি কিছুটা বিভ্রান্ত। আমার প্রায় 50 টি ফাইল সহ একটি বড় প্রকল্প রয়েছে এবং আমার এই সমস্ত ফাইলের জন্য বিশ্বব্যাপী ভেরিয়েবলগুলি সংজ্ঞায়িত করতে হবে।

আমি যা করেছি তা ছিল আমার প্রকল্পের main.pyফাইলগুলিতে সেগুলি সংজ্ঞায়িত করা , যেমন:

# ../myproject/main.py

# Define global myList
global myList
myList = []

# Imports
import subfile

# Do something
subfile.stuff()
print(myList[0])

আমি ব্যবহার করার চেষ্টা করছি myListsubfile.py, নিম্নলিখিত হিসাবে

# ../myproject/subfile.py

# Save "hey" into myList
def stuff():
    globals()["myList"].append("hey")

অন্য একটি উপায়ে চেষ্টা করেছি, তবে কাজও হয়নি

# ../myproject/main.py

# Import globfile    
import globfile

# Save myList into globfile
globfile.myList = []

# Import subfile
import subfile

# Do something
subfile.stuff()
print(globfile.myList[0])

এবং ভিতরে subfile.pyআমি এই ছিল:

# ../myproject/subfile.py

# Import globfile
import globfile

# Save "hey" into myList
def stuff():
    globfile.myList.append("hey")

কিন্তু আবার, এটি কাজ করে না। আমি কীভাবে এটি বাস্তবায়ন করব? আমি বুঝতে পারি যে এটি সেভাবে কাজ করতে পারে না, যখন দুটি ফাইল সত্যই একে অপরকে চেনে না (ভাল সাবফিলটি মূল জানে না), তবে আমি কীভাবে করব তা ভাবতে পারি না, আইও রচনা বা আচার ব্যবহার না করে, যা আমি করতে চাই না।


আসলে, আপনার দ্বিতীয় পদ্ধতির আমার জন্য ঠিক কাজ করে। main.py সঠিকভাবে "আরে" মুদ্রণ করে। আপনি কি আমাকে "এটি কাজ করে না" দ্বারা আরও নির্দিষ্ট করে রাখতে পারেন?
রডিয়ান

@ প্রজনন: চক্র আমদানি - সাবফাইলে কোডটি গ্লোব ফাইল আমদানি করার চেষ্টা করে, যা এতে দেহ নিজেই আমদানি করে
jsbueno

1
NameError: name 'myList' is not definedmain.pyলাইন থেকেprint(globfile.myList[0])

উত্তর:


318

সমস্যাটি আপনি নির্ধারণ myListকরেছেন main.pyতবে subfile.pyএটি ব্যবহার করা দরকার। এই সমস্যাটি সমাধান করার জন্য এখানে একটি পরিষ্কার উপায় রয়েছে: সমস্ত গ্লোবালগুলিকে একটি ফাইলে সরান, আমি এই ফাইলটিকে কল করি settings.py। এই ফাইলটি গ্লোবালগুলি সংজ্ঞায়িত করতে এবং সেগুলির সূচনা করার জন্য দায়ী:

# settings.py

def init():
    global myList
    myList = []

পরবর্তী, আপনার subfileগ্লোবালগুলি আমদানি করতে পারেন:

# subfile.py

import settings

def stuff():
    settings.myList.append('hey')

নোট যে subfileকল করে না init()- সেই কাজটি অন্তর্ভুক্ত main.py:

# main.py

import settings
import subfile

settings.init()          # Call only once
subfile.stuff()         # Do stuff with global var
print settings.myList[0] # Check the result

এইভাবে, আপনি একাধিকবার বৈশ্বিক ভেরিয়েবল আরম্ভ করা এড়াতে আপনার লক্ষ্য অর্জন করেন।


40
আমি সাধারণ পদ্ধতির পছন্দ করি তবে পুরো জিনিসটি পছন্দ করে না init()। মডিউলগুলি কেবলমাত্র প্রথমবার আমদানি করা হলে তা মূল্যায়ন করা হয়, সুতরাং মডিউলটির শরীরে সেই পরিবর্তনগুলি আরম্ভ করা পুরোপুরি ঠিক।
কर्क স্ট্রুজার

19
+1 কার্ক: আমি সম্মত। তবে, আমার পদ্ধতির ক্ষেত্রে বাধা দেওয়া যায় যেখানে অন্যান্য প্রোগ্রামগুলি মূল প্রোগ্রাম শুরু হওয়ার আগে গ্লোবালস.মাইলিস্টে পরিবর্তন করে mod
হাই ভু

2
আপনার এটিকে গ্লোবালগুলি বাদ দিয়ে অন্য কিছু বলা উচিত, এটি একটি অন্তর্নিহিত নাম। পাইলিন্ট হুঁশিয়ারি দিয়েছে: "বিল্ট-ইন 'গ্লোবালগুলি (পুনরায় সংজ্ঞায়িত
বিল্টিন

ধন্যবাদ। এই ফাইল স্ট্রাকচার (যেমন সেটিংস.পি থেকে গ্লোবাল ভেরিয়েবল আমদানি) করে Eclipse PyDev এ প্রদর্শিত "আমদানি থেকে অপরিজ্ঞাত পরিবর্তনশীল" ত্রুটিগুলি কীভাবে সরিয়ে ফেলা যায়? পাইডেভের ত্রুটিটি আমাকে অক্ষম করতে হয়েছিল , এটি আদর্শ নয়।
ফ্রাঙ্ক ডারননকোর্ট

@ ফ্র্যাঙ্কডেরননকোর্ট আমি দুঃখিত, আমি গ্রহনটি ব্যবহার করি না তাই আপনার চেয়ে আমি আরও বেশি নির্বিকার।
হাই ভু

93

মডিউলগুলি জুড়ে গ্লোবাল ভেরিয়েবলগুলি ভাগ করে নেওয়ার বিষয়ে পাইথনের নথিটি দেখুন :

একক প্রোগ্রামের মধ্যে মডিউলগুলি জুড়ে তথ্য ভাগ করে নেওয়ার ক্যানোনিকাল উপায় হল একটি বিশেষ মডিউল (প্রায়শই কনফিগার বা সিএফজি নামে পরিচিত) তৈরি করা।

config.py:

x = 0   # Default value of the 'x' configuration setting

আপনার অ্যাপ্লিকেশনটির সমস্ত মডিউলগুলিতে কনফিগার মডিউলটি আমদানি করুন; মডিউলটি তখন বিশ্বব্যাপী নাম হিসাবে উপলব্ধ হয়।

main.py:

import config
print (config.x)

অথবা

from config import x
print (x)

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


1
লাইফসেভার - ঠিক সেই লিঙ্কটির জন্য!
toonarmycaptain

4
এটি গ্রহণযোগ্য উত্তরের চেয়ে ক্লিনার পদ্ধতির মতো বলে মনে হচ্ছে।
জয়েসি

2
নোট করুন যে আপনি কেবল ব্যবহার xকরে সেট করতে পারবেন নাfrom config import ximport config
ইয়ারিভ

1
সহজ সমাধান! ধন্যবাদ
ব্যবহারকারী 1297406

22

আপনি পাইথন গ্লোবাল ভেরিয়েবলগুলি "মডিউল" ভেরিয়েবল হিসাবে ভাবতে পারেন - এবং এগুলি সি থেকে প্রচলিত "গ্লোবাল ভেরিয়েবল" এর চেয়ে অনেক বেশি কার্যকর

একটি গ্লোবাল ভেরিয়েবল আসলে একটি মডিউল এর মধ্যে সংজ্ঞায়িত করা হয় __dict__এবং মডিউল বৈশিষ্ট্য হিসাবে যে মডিউল বাইরে থেকে অ্যাক্সেস করা যেতে পারে।

সুতরাং, আপনার উদাহরণে:

# ../myproject/main.py

# Define global myList
# global myList  - there is no "global" declaration at module level. Just inside
# function and methods
myList = []

# Imports
import subfile

# Do something
subfile.stuff()
print(myList[0])

এবং:

# ../myproject/subfile.py

# Save "hey" into myList
def stuff():
     # You have to make the module main available for the 
     # code here.
     # Placing the import inside the function body will
     # usually avoid import cycles - 
     # unless you happen to call this function from 
     # either main or subfile's body (i.e. not from inside a function or method)
     import main
     main.mylist.append("hey")

1
বাহ, সাধারণত এক অপরিসীম লুপটি পেতে দুটি ফাইল একে অপরকে আমদানি করে বলে আশা করে।
নিখিল ভিজে

2
হা প্রথম নজরে দেখে মনে হচ্ছে, তাই না? ডিএফ স্টাফগুলিতে () কী ঘটে তা হ'ল ফাইলটি লোড হয়ে গেলে আমদানি চলবে না it যখন স্টাফ () ফাংশন বলা হবে তখনই এটি চলে। সুতরাং মূল দিয়ে শুরু করে আমরা সাবফিল আমদানি করি এবং তারপরে সাবফিল.স্টফ () কে কল করি যা পরে আমদানি করে প্রধান ... কোন লুপ নয়, কেবল একবার মুখ্য আমদানি করুন। আমদানি চক্র সম্পর্কে subfile.py উদাহরণে নোটটি দেখুন।
জন

11

ব্যবহার from your_file import *করা আপনার সমস্যার সমাধান করা উচিত। এটি সমস্ত কিছু সংজ্ঞায়িত করে যাতে এটি বিশ্বব্যাপী উপলভ্য হয় (অবশ্যই আমদানিতে স্থানীয় ভেরিয়েবলগুলি বাদে)।

উদাহরণ স্বরূপ:

##test.py:

from pytest import *

print hello_world

এবং:

##pytest.py

hello_world="hello world!"

4
আপনি যদি এমন একটি পরিবর্তনশীলকে বরাদ্দ করেন তবে
jsbueno

5
আমি ব্যক্তিগতভাবে যেকোন import *মূল্যে ব্যবহার এড়িয়ে চলি যাতে উল্লেখগুলি স্পষ্ট হয় (এবং বিভ্রান্তিকর হয় না) পাশাপাশি, আপনি কখনই *কোনও মডিউলে সমস্ত " " রেফারেন্স ব্যবহার করেছেন ?
থারস্মমনার

19
আমদানি করবেন না *। আপনার গ্লোবাল ভেরিয়েবলগুলি আর সিঙ্কে থাকবে না। প্রতিটি মডিউল তার নিজস্ব অনুলিপি গ্রহণ করে। ভেরিয়েবলকে একটি ফাইলে পরিবর্তন করা অন্য কোনও ক্ষেত্রে প্রতিফলিত হবে না। এটিও ডকস.প্যাথন.আর.
Isa

8

হাই ভু উত্তর দুর্দান্ত কাজ করে, কেবল একটি মন্তব্য:

আপনি যদি অন্য মডিউলে গ্লোবাল ব্যবহার করছেন এবং আপনি গ্লোবালকে গতিশীলভাবে সেট করতে চান তবে বৈশ্বিক ভেরিয়েবলগুলি সেট করার পরে অন্যান্য মডিউলগুলি আমদানিতে মনোযোগ দিন, উদাহরণস্বরূপ:

# settings.py
def init(arg):
    global myList
    myList = []
    mylist.append(arg)


# subfile.py
import settings

def print():
    settings.myList[0]


# main.py
import settings
settings.init("1st")     # global init before used in other imported modules
                         # Or else they will be undefined

import subfile    
subfile.print()          # global usage

4

আপনার ২ য় প্রচেষ্টা নিখুঁতভাবে কাজ করবে এবং আপনি বিশ্বব্যাপী উপলব্ধ থাকতে চান এমন পরিবর্তনশীল নামগুলি হ্যান্ডেল করার জন্য এটি সত্যিই একটি ভাল উপায়। তবে আপনার শেষ লাইনে একটি নাম ত্রুটি রয়েছে। এটি কেমন হওয়া উচিত তা এখানে:

# ../myproject/main.py

# Import globfile    
import globfile

# Save myList into globfile
globfile.myList = []

# Import subfile
import subfile

# Do something
subfile.stuff()
print(globfile.myList[0])

শেষ লাইনটি দেখুন? মাইলিস্ট হ'ল গ্লোব ফাইলের আধিকারিক, সাবফিল নয়। এটি আপনার ইচ্ছা মতো কাজ করবে।

মাইক

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