পাইথনে আমি কীভাবে পরিবর্তনশীল ভেরিয়েবলগুলি সম্পাদন করতে পারি?
উদাহরণস্বরূপ: এখানে একটি বিশদ ম্যানুয়াল এন্ট্রি রয়েছে V
আমি শুনেছি এটি সাধারণভাবে খারাপ ধারণা এবং এটি পাইথনের একটি সুরক্ষা গর্ত hole এটা কি সত্যি?
পাইথনে আমি কীভাবে পরিবর্তনশীল ভেরিয়েবলগুলি সম্পাদন করতে পারি?
উদাহরণস্বরূপ: এখানে একটি বিশদ ম্যানুয়াল এন্ট্রি রয়েছে V
আমি শুনেছি এটি সাধারণভাবে খারাপ ধারণা এবং এটি পাইথনের একটি সুরক্ষা গর্ত hole এটা কি সত্যি?
উত্তর:
এটি সম্পাদন করতে আপনি অভিধান ব্যবহার করতে পারেন । অভিধানগুলি কী এবং মানগুলির স্টোর।
>>> dct = {'x': 1, 'y': 2, 'z': 3}
>>> dct
{'y': 2, 'x': 1, 'z': 3}
>>> dct["y"]
2
সুরক্ষা ঝুঁকি ছাড়াই পরিবর্তনশীল ভেরিয়েবলের প্রভাব অর্জন করতে আপনি ভেরিয়েবল কী নাম ব্যবহার করতে পারেন।
>>> x = "spam"
>>> z = {x: "eggs"}
>>> z["spam"]
'eggs'
এমন ক্ষেত্রে যেখানে আপনি এমন কিছু করার কথা ভাবছেন
var1 = 'foo'
var2 = 'bar'
var3 = 'baz'
...
একটি তালিকা ডিকের চেয়ে আরও উপযুক্ত হতে পারে। একটি তালিকা পূর্ণসংখ্যার সূচকগুলি সহ অবজেক্টের ক্রমযুক্ত ক্রম উপস্থাপন করে:
lst = ['foo', 'bar', 'baz']
print(lst[1]) # prints bar, because indices start at 0
lst.append('potatoes') # lst is now ['foo', 'bar', 'baz', 'potatoes']
আদেশ সিকোয়েন্স জন্য, তালিকা কারণ তালিকা সূচক আদেশ, মধ্যে পুনরাবৃত্তির সমর্থন পূর্ণসংখ্যা কী এর মাধ্যমে dicts চেয়ে আরও বেশি সুবিধাজনক হয় slicing , append
, এবং অন্যান্য অপারেশন করে একটি অভি সঙ্গে বিশ্রী কী ব্যবস্থাপনা প্রয়োজন।
getattr
নামের সাথে কোনও অবজেক্টের একটি বৈশিষ্ট্য পেতে অন্তর্নির্মিত ফাংশনটি ব্যবহার করুন । প্রয়োজন মতো নামটি সংশোধন করুন।
obj.spam = 'eggs'
name = 'spam'
getattr(obj, name) # returns 'eggs'
এটি একটি ভাল ধারণা না. আপনি যদি কোনও বিশ্বব্যাপী ভেরিয়েবল অ্যাক্সেস করে থাকেন তবে আপনি এটি ব্যবহার করতে পারেন globals()
।
>>> a = 10
>>> globals()['a']
10
আপনি যদি স্থানীয় স্কোপে কোনও পরিবর্তনশীল অ্যাক্সেস করতে চান locals()
তবে আপনি ব্যবহার করতে পারেন তবে আপনি ফেরত ডিকের মান নির্ধারণ করতে পারবেন না।
getattr
একটি অভিধানে আপনার ভেরিয়েবলগুলি ব্যবহার বা সঞ্চয় করে তারপরে নাম দ্বারা অ্যাক্সেস করা এর থেকে ভাল সমাধান solution
x = "foo"
এবং locals()["x"] = "bar"
ব্যবহার জাইথন 2.5.2 এর print x
আউটপুট দেয় bar
। এটি ম্যাক্সিমোতে অন ডিমান্ড অটোমেশন স্ক্রিপ্ট দিয়ে পরীক্ষা করা হয়েছিল ।
আপনি যখনই ভেরিয়েবল ভেরিয়েবল ব্যবহার করতে চান তখন কোনও অভিধান ব্যবহার করা আরও ভাল। সুতরাং লেখার পরিবর্তে
$foo = "bar"
$$foo = "baz"
তুমি লেখ
mydict = {}
foo = "bar"
mydict[foo] = "baz"
এইভাবে আপনি দুর্ঘটনাক্রমে পূর্বে বিদ্যমান ভেরিয়েবলগুলি (যা সুরক্ষা দিক) ওভাররাইট করতে পারবেন না এবং আপনার বিভিন্ন "নেমস্পেস" থাকতে পারে।
নতুন কোডাররা মাঝে মাঝে এই জাতীয় কোড লিখেন:
my_calculator.button_0 = tkinter.Button(root, text=0)
my_calculator.button_1 = tkinter.Button(root, text=1)
my_calculator.button_2 = tkinter.Button(root, text=2)
...
কোডারটি নামযুক্ত ভেরিয়েবলগুলির একটি গাদা দিয়ে ও ( এম * এন ) এর কোডিং প্রচেষ্টা সহ রেখে যায় , যেখানে এম নামযুক্ত ভেরিয়েবলের সংখ্যা এবং এন ভেরিয়েবলগুলির গ্রুপটি অ্যাক্সেস করার প্রয়োজনের সংখ্যা (সৃষ্টি সহ) )। আরও চমকপ্রদ শিক্ষানবিস পর্যবেক্ষণ করে যে those প্রতিটি লাইনের মধ্যে কেবলমাত্র তফাতটি এমন একটি সংখ্যা যা কোনও নিয়মের উপর নির্ভর করে পরিবর্তিত হয় এবং লুপটি ব্যবহারের সিদ্ধান্ত নেয়। তবে কীভাবে এই পরিবর্তনশীল নামগুলি পরিবর্তনশীলভাবে তৈরি করা যায় তা নিয়ে তারা আটকে যায় এবং এ জাতীয় কিছু চেষ্টা করতে পারে:
for i in range(10):
my_calculator.('button_%d' % i) = tkinter.Button(root, text=i)
তারা শীঘ্রই আবিষ্কার করবে যে এটি কার্যকর হয় না।
প্রোগ্রামটি যদি স্বেচ্ছাসেবী পরিবর্তনশীল "নামগুলির" প্রয়োজন হয়, তবে অন্য উত্তরে যেমন ব্যাখ্যা করা হয়েছে তেমন একটি অভিধানই সেরা পছন্দ। যাইহোক, আপনি যদি সহজেই অনেকগুলি ভেরিয়েবল তৈরি করার চেষ্টা করছেন এবং আপনি তাদের পূর্ণসংখ্যার ক্রমিক সহ উল্লেখ করে কিছু মনে করেন না, আপনি সম্ভবত এটির জন্য সন্ধান করছেন list
। এটি বিশেষত সত্য যদি আপনার ডেটা একজাতীয় হয়, যেমন দৈনিক তাপমাত্রা পাঠ, সাপ্তাহিক কুইজ স্কোর বা গ্রাফিক্যাল উইজেটের গ্রিড।
এটি নিম্নলিখিত হিসাবে একত্রিত হতে পারে:
my_calculator.buttons = []
for i in range(10):
my_calculator.buttons.append(tkinter.Button(root, text=i))
এটি list
একটি বোধগম্যতার সাথে এক লাইনেও তৈরি করা যেতে পারে:
my_calculator.buttons = [tkinter.Button(root, text=i) for i in range(10)]
উভয় ক্ষেত্রেই ফলাফল একটি জনবহুল list
, প্রথম উপাদানটি অ্যাক্সেস সহ my_calculator.buttons[0]
, পরবর্তী সঙ্গে my_calculator.buttons[1]
এবং আরও অনেক কিছু। "বেস" ভেরিয়েবল নামটির নাম হয়ে যায় list
এবং এটি অ্যাক্সেস করার জন্য বিবিধ পরিচায়ক ব্যবহৃত হয়।
পরিশেষে, অন্যান্য ডেটা স্ট্রাকচারগুলি ভুলে যাবেন না, যেমন set
- এটি একটি অভিধানের সাথে সমান, প্রতিটি "নামের" সাথে এর সাথে কোনও মান সংযুক্ত থাকে না। আপনার যদি কেবল অবজেক্টগুলির একটি "ব্যাগ" দরকার হয় তবে এটি দুর্দান্ত পছন্দ হতে পারে। এর মতো কিছু পরিবর্তে:
keyword_1 = 'apple'
keyword_2 = 'banana'
if query == keyword_1 or query == keyword_2:
print('Match.')
আপনার এটি হবে:
keywords = {'apple', 'banana'}
if query in keywords:
print('Match.')
একটি ব্যবহার করুন list
অনুরূপ বস্তু একটি ক্রম, একটি জন্য set
বস্তুর একটি ইচ্ছামত-বরাত ব্যাগ, অথবা একটি জন্য dict
যুক্ত মান নামের একটি ব্যাগ জন্য।
অভিধানের পরিবর্তে আপনি namedtuple
সংগ্রহের মডিউলটিও ব্যবহার করতে পারেন যা অ্যাক্সেসকে আরও সহজ করে তোলে।
উদাহরণ স্বরূপ:
# using dictionary
variables = {}
variables["first"] = 34
variables["second"] = 45
print(variables["first"], variables["second"])
# using namedtuple
Variables = namedtuple('Variables', ['first', 'second'])
vars = Variables(34, 45)
print(vars.first, vars.second)
আপনি যদি কোনও অবজেক্ট ব্যবহার করতে না চান তবে আপনি setattr()
আপনার বর্তমান মডিউলটির ভিতরে ব্যবহার করতে পারেন :
import sys
current_module = module = sys.modules[__name__] # i.e the "file" where your code is written
setattr(current_module, 'variable_name', 15) # 15 is the value you assign to the var
print(variable_name) # >>> 15, created from a string
__dict__
ভেরিয়েবলের সাথে কাজ করে না । আমি আশ্চর্য হই যে গতিশীলভাবে কোনও বৈশ্বিক পরিবর্তনশীল তৈরি করার জন্য যদি কোনও সাধারণ প্রক্রিয়া থাকে ।
globals()
এটি করতে পারেন
SimpleNamespace
শ্রেণী সাথে নতুন বৈশিষ্ট্যাবলী তৈরি করতে ব্যবহার করা যেতে পারে setattr
, অথবা উপশ্রেণী SimpleNamespace
এবং নতুন গুণের নাম (ভেরিয়েবল) যোগ করতে আপনার নিজস্ব ফাংশন তৈরি করুন।
from types import SimpleNamespace
variables = {"b":"B","c":"C"}
a = SimpleNamespace(**variables)
setattr(a,"g","G")
a.g = "G+"
something = a.a
আমি এই প্রশ্নের উত্তর দিচ্ছি: একটি স্ট্রিংয়ের নাম অনুসারে একটি ভেরিয়েবলের মান কীভাবে পাবেন? যা এই প্রশ্নের লিঙ্কযুক্ত সদৃশ হিসাবে বন্ধ রয়েছে।
প্রশ্নে ভেরিয়েবল একটি বস্তু (যেমন একটি বর্গ অংশ) অংশ, তাহলে কিছু দরকারী ফাংশন ঠিক অর্জন করার যে hasattr
, getattr
এবং setattr
।
সুতরাং উদাহরণস্বরূপ আপনি থাকতে পারেন:
class Variables(object):
def __init__(self):
self.foo = "initial_variable"
def create_new_var(self,name,value):
setattr(self,name,value)
def get_var(self,name):
if hasattr(self,name):
return getattr(self,name)
else:
raise("Class does not have a variable named: "+name)
তারপরে আপনি এটি করতে পারেন:
v = Variables()
v.get_var("foo")
"Initial_variable"
v.create_new_var(v.foo,"is actually not initial")
v.initial_variable
"আসলে প্রাথমিক নয়"
ব্যবহার globals()
আপনি প্রকৃতপক্ষে গ্লোবাল স্কোপকে পরিবর্তনশীল বরাদ্দ করতে পারেন উদাহরণস্বরূপ, আপনি যদি 10 বৈকল্পিক চান যা বিশ্বব্যাপী সুযোগে অ্যাক্সেস করা যায় i_1
, i_2
... i_10
:
for i in range(10):
globals()['i_{}'.format(i)] = 'a'
এটি এই 10 টি ভেরিয়েবলের সমস্তকে 'এ' বরাদ্দ করবে, অবশ্যই আপনি গতিগতভাবেও মান পরিবর্তন করতে পারবেন। এই সমস্ত পরিবর্তনশীল এখন অন্যান্য বিশ্বব্যাপী ঘোষিত ভেরিয়েবলের মতো অ্যাক্সেস করা যায়:
>>> i_5
'a'
এই আচরণটি অর্জন করতে আপনাকে globals()
বিল্ট ইন মেথড ব্যবহার করতে হবে:
def var_of_var(k, v):
globals()[k] = v
print variable_name # NameError: name 'variable_name' is not defined
some_name = 'variable_name'
globals()[some_name] = 123
print variable_name # 123
some_name = 'variable_name2'
var_of_var(some_name, 456)
print variable_name2 # 456
Sensকমত্যটি এর জন্য অভিধান ব্যবহার করা - অন্যান্য উত্তরগুলি দেখুন। এটি বেশিরভাগ ক্ষেত্রেই এটি একটি ভাল ধারণা, তবে এর থেকে অনেকগুলি দিক উত্থাপিত হয়:
বলেছিল, আমি একটি ভেরিয়েবল ভেরিয়েবল ম্যানেজার প্রয়োগ করেছি ক্লাস যা উপরোক্ত কিছু ধারণাগুলি সরবরাহ করে। এটি অজগর 2 এবং 3 এর জন্য কাজ করে।
আপনি ক্লাসটি এভাবে ব্যবহার করবেন :
from variableVariablesManager import VariableVariablesManager
myVars = VariableVariablesManager()
myVars['test'] = 25
print(myVars['test'])
# define a const variable
myVars.defineConstVariable('myconst', 13)
try:
myVars['myconst'] = 14 # <- this raises an error, since 'myconst' must not be changed
print("not allowed")
except AttributeError as e:
pass
# rename a variable
myVars.renameVariable('myconst', 'myconstOther')
# preserve locality
def testLocalVar():
myVars = VariableVariablesManager()
myVars['test'] = 13
print("inside function myVars['test']:", myVars['test'])
testLocalVar()
print("outside function myVars['test']:", myVars['test'])
# define a global variable
myVars.defineGlobalVariable('globalVar', 12)
def testGlobalVar():
myVars = VariableVariablesManager()
print("inside function myVars['globalVar']:", myVars['globalVar'])
myVars['globalVar'] = 13
print("inside function myVars['globalVar'] (having been changed):", myVars['globalVar'])
testGlobalVar()
print("outside function myVars['globalVar']:", myVars['globalVar'])
আপনি যদি একই ধরণের সাথে ভেরিয়েবলের ওভাররাইটিংকে অনুমতি দিতে চান তবে:
myVars = VariableVariablesManager(enforceSameTypeOnOverride = True)
myVars['test'] = 25
myVars['test'] = "Cat" # <- raises Exception (different type on overwriting)
অজগরকে আমি ৩.7.৩ এ চেষ্টা করেছি, আপনি গ্লোবাল () বা ভার্স () ব্যবহার করতে পারেন
>>> food #Error
>>> milkshake #Error
>>> food="bread"
>>> drink="milkshake"
>>> globals()[food] = "strawberry flavor"
>>> vars()[drink] = "chocolate flavor"
>>> bread
'strawberry flavor'
>>> milkshake
'chocolate flavor'
>>> globals()[drink]
'chocolate flavor'
>>> vars()[food]
'strawberry flavor'
তথ্যসূত্র: https://www.daniweb.com/programming/software-development/threads/111526/setting-a-string-as-a-variable- name#
post548936
ভেরিয়েবলের যে কোনও সেটও ক্লাসে গুটিয়ে রাখা যায়। রান টাইম চলাকালীন __dict__ বৈশিষ্ট্যের মাধ্যমে অন্তর্নির্মিত অভিধানটি সরাসরি অ্যাক্সেসের মাধ্যমে ক্লাসে "পরিবর্তনশীল" ভেরিয়েবল যুক্ত করা যেতে পারে।
নিম্নলিখিত কোডটি ভেরিয়েবল শ্রেণি সংজ্ঞায়িত করে, যা নির্মাণের সময় তার উদাহরণগুলিতে ভেরিয়েবল (এই ক্ষেত্রে বৈশিষ্ট্যগুলিতে) যুক্ত করে। পরিবর্তিত নামগুলি একটি নির্দিষ্ট তালিকা থেকে নেওয়া হয় (যা উদাহরণস্বরূপ, প্রোগ্রাম কোড দ্বারা তৈরি করা যেতে পারে):
# some list of variable names
L = ['a', 'b', 'c']
class Variables:
def __init__(self, L):
for item in L:
self.__dict__[item] = 100
v = Variables(L)
print(v.a, v.b, v.c)
#will produce 100 100 100