পাইথনে পাইথন কোডযুক্ত একটি স্ট্রিং আমি কীভাবে কার্যকর করব?
পাইথনে পাইথন কোডযুক্ত একটি স্ট্রিং আমি কীভাবে কার্যকর করব?
উত্তর:
বিবৃতিগুলির জন্য, exec(string)
(পাইথন 2/3) বা exec string
(পাইথন 2) ব্যবহার করুন:
>>> mycode = 'print "hello world"'
>>> exec(mycode)
Hello world
যখন আপনার একটি এক্সপ্রেশনটির মান প্রয়োজন হয় তখন ব্যবহার করুন eval(string)
:
>>> x = eval("2+2")
>>> x
4
তবে, প্রথম পদক্ষেপটি নিজেকে জিজ্ঞাসা করা উচিত যদি আপনার সত্যই প্রয়োজন হয়। সম্পাদনকারী কোডটি সাধারণত শেষ অবলম্বনের অবস্থান হওয়া উচিত: এটি ধীর, কুরুচিপূর্ণ এবং বিপজ্জনক যদি এটিতে ব্যবহারকারীর প্রবেশের কোড থাকতে পারে। আপনার সর্বদা বিকল্পগুলি যেমন উচ্চতর ক্রম ফাংশনগুলির দিকে নজর দেওয়া উচিত তা দেখার জন্য যে এগুলি আরও ভালভাবে আপনার চাহিদা পূরণ করতে পারে।
if s=='foo': x.foo = 42 elif s=='bar': x.bar = 42
ইত্যাদি জাতীয় কিছু যা তারা তখন লিখতে পারে exec ("x.%s = 42" % s)
। এই সাধারণ ক্ষেত্রে (যেখানে আপনার কেবল স্ট্রিংয়ে থাকা কোনও অবজেক্টের বৈশিষ্ট্য অ্যাক্সেস করতে হবে) সেখানে আরও দ্রুত, ক্লিনার এবং নিরাপদ ফাংশন রয়েছে getattr
: কেবল getattr(x, s) = 42
একই জিনিসটির অর্থ বোঝাতে লিখুন ।
setattr(x, s, 42)
? আমি চেষ্টা করেছিলাম getattr(x, 2) = 42
এবং এটি দিয়ে ব্যর্থ হয়েছিলcan't assign to function call: <string>, line 1
setattr(x, s, 42)
সঠিক বাক্য গঠন। আশ্চর্য হয়ে যায় যে ত্রুটিটি ধরা পড়তে এত দিন লেগেছিল। যাই হোক, বিন্দু যে getattr
এবং setattr
বিকল্প হয় exec
যখন আপনি চান আপনার সব একটি অবাধ সদস্য পেতে হয়, স্ট্রিং-এর দ্বারা তাকিয়ে।
উদাহরণস্বরূপ একটি স্ট্রিং এক্সিকিউট ফাংশন ব্যবহার করে কোড হিসাবে কার্যকর করা হয়।
import sys
import StringIO
# create file-like string to capture output
codeOut = StringIO.StringIO()
codeErr = StringIO.StringIO()
code = """
def f(x):
x = x + 1
return x
print 'This is my output.'
"""
# capture output and errors
sys.stdout = codeOut
sys.stderr = codeErr
exec code
# restore stdout and stderr
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
print f(4)
s = codeErr.getvalue()
print "error:\n%s\n" % s
s = codeOut.getvalue()
print "output:\n%s" % s
codeOut.close()
codeErr.close()
exec
(যদি না আপনি জানেন যে কোড স্ট্রিং কোনও বিশ্বস্ত উত্স থেকে আসে)।
eval
এবং exec
সঠিক সমাধান এবং এগুলি নিরাপদ উপায়ে ব্যবহার করা যেতে পারে ।
যেমন আলোচনা হয়েছে পাইথনের রেফারেন্স ম্যানুয়ালটিতে হয়েছে এবং এই টিউটোরিয়ালে পরিষ্কারভাবে ব্যাখ্যা করা হয়েছে , eval
এবং exec
ফাংশনগুলি দুটি অতিরিক্ত পরামিতি নেয় যা কোনও ব্যবহারকারীকে কী কী বৈশ্বিক এবং স্থানীয় ফাংশন এবং ভেরিয়েবল উপলব্ধ তা নির্দিষ্ট করতে দেয় to
উদাহরণ স্বরূপ:
public_variable = 10
private_variable = 2
def public_function():
return "public information"
def private_function():
return "super sensitive information"
# make a list of safe functions
safe_list = ['public_variable', 'public_function']
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
# add any needed builtins back in
safe_dict['len'] = len
>>> eval("public_variable+2", {"__builtins__" : None }, safe_dict)
12
>>> eval("private_variable+2", {"__builtins__" : None }, safe_dict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'private_variable' is not defined
>>> exec("print \"'%s' has %i characters\" % (public_function(), len(public_function()))", {"__builtins__" : None}, safe_dict)
'public information' has 18 characters
>>> exec("print \"'%s' has %i characters\" % (private_function(), len(private_function()))", {"__builtins__" : None}, safe_dict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'private_function' is not defined
সংক্ষেপে আপনি নামটি স্থান নির্ধারণ করছেন যেখানে কোডটি কার্যকর করা হবে।
eval
বা exec
এটি ব্যবহারের উদ্দেশ্যে exec(input("Type what you want"))
? এমন অনেকগুলি মামলা রয়েছে যেখানে কোনও প্রোগ্রাম একটি গণনার ফলে কোনও পদ্ধতি বা একটি ফাংশন লিখতে পারে; ফলস্বরূপ ফাংশনগুলি কোনও ভাল এবং লিখিত প্রোগ্রামের অন্য কোনও অংশের মতোই নিরাপদ এবং দ্রুত (একবার মূল্যায়ন করা) হবে। কোনও অনিরাপদ প্রোগ্রাম exec
থাকা কোনও অনিরাপদ প্রোগ্রামের দ্বারা ক্ষতি সাধন করা তার চেয়ে বেশি বিপজ্জনক নয় কারণ প্রোগ্রামটি exec
কোনও নতুন সুযোগ দেয় না।
eval()
শুধু এক্সপ্রেশন জন্য, যখন হয় eval('x+1')
কাজ, eval('x=1')
উদাহরণস্বরূপ কাজ করবে না। সেক্ষেত্রে এটি ব্যবহার করা exec
আরও ভাল, বা আরও ভাল: আরও ভাল সমাধান খোঁজার চেষ্টা করুন :)
exec
এবংeval
exec
এবং eval
এটির উপর অত্যন্ত নীচু ধারণা রয়েছে।উপরের উত্তর থেকে (জোর দেওয়া খনি):
বিবৃতি, ব্যবহারের জন্য
exec
।যখন আপনার একটি এক্সপ্রেশনটির মান প্রয়োজন হয় তখন ব্যবহার করুন
eval
।তবে, প্রথম পদক্ষেপটি নিজেকে জিজ্ঞাসা করা উচিত যদি আপনার সত্যই প্রয়োজন হয়। সম্পাদনকারী কোডটি সাধারণত শেষ অবলম্বনের অবস্থান হওয়া উচিত : এটি ধীর, কুরুচিপূর্ণ এবং বিপজ্জনক যদি এটিতে ব্যবহারকারীর প্রবেশের কোড থাকতে পারে। আপনার সর্বদা বিকল্পগুলি যেমন উচ্চতর ক্রম ফাংশনগুলির দিকে নজর দেওয়া উচিত তা দেখার জন্য যে এগুলি আরও ভালভাবে আপনার চাহিদা পূরণ করতে পারে।
স্ট্রিংগুলিতে নামের সাথে ভেরিয়েবলের মানগুলি সেট করুন এবং পান
[যখন
eval
] কাজ করবে, সাধারণত প্রোগ্রামের নিজস্ব অর্থ বহনকারী পরিবর্তনশীল নাম ব্যবহার করার পরামর্শ দেওয়া হয় না।পরিবর্তে, আরও একটি ডিক ব্যবহার করুন।
Http://lucumr.pocoo.org/2011/2/1/exec-in-python/ থেকে (জোর দেওয়া খনি)
পাইথন পিএইচপি নয়
পাইথন রীতিমতো প্রতিরোধ করার চেষ্টা করবেন না কারণ অন্য কিছু ভাষা এটি আলাদাভাবে করে। নেমস্পেসগুলি একটি কারণে পাইথনে রয়েছে এবং কেবল কারণ এটি আপনাকে সরঞ্জাম দেয়
exec
এটির অর্থ এই নয় যে আপনার সেই সরঞ্জামটি ব্যবহার করা উচিত।
থেকে http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html (জোর খনি)
সুতরাং eval নিরাপদ নয়, এমনকি যদি আপনি সমস্ত গ্লোবাল এবং বিল্টিনগুলি সরিয়ে দেন!
এভাল () রক্ষা করার জন্য এই সমস্ত প্রচেষ্টা নিয়ে সমস্যা হ'ল তারা কালো তালিকাভুক্ত । তারা স্পষ্টভাবে এমন জিনিস সরিয়ে দেয় যা বিপজ্জনক হতে পারে। এটি একটি হেরে যাওয়া যুদ্ধ, কারণ যদি তালিকায় কেবল একটি আইটেম বাকি থাকে তবে আপনি সিস্টেমে আক্রমণ করতে পারেন ।
সুতরাং, কি eval নিরাপদ করা যেতে পারে? বলা কঠিন. এই মুহুর্তে, আমার সর্বোত্তম অনুমান যে আপনি কোনও ডাবল আন্ডারস্কোর ব্যবহার করতে না পারলে আপনি কোনও ক্ষতি করতে পারবেন না, তাই আপনি যদি ডাবল আন্ডারস্কোর সহ কোনও স্ট্রিং বাদ দেন তবে আপনি নিরাপদ। হতে পারে...
থেকে http://stupidpythonideas.blogspot.it/2013/05/why-evalexec-is-bad.html (জোর খনি):
প্রথমত,
exec
আপনার কোডটি পড়া মানুষের পক্ষে আরও কঠিন করে তোলে । কী ঘটছে তা বের করার জন্য, আমাকে কেবল আপনার কোডটি পড়তে হবে না, আমাকে আপনার কোডটি পড়তে হবে, এটি স্ট্রিংটি কী উত্পন্ন করতে চলেছে তা বের করতে হবে, তারপরে সেই ভার্চুয়াল কোডটি পড়তে হবে। সুতরাং, আপনি যদি কোনও দলে কাজ করছেন, বা ওপেন সোর্স সফ্টওয়্যার প্রকাশ করছেন, বা স্ট্যাকওভারফ্লোয়ের মতো কোথাও সাহায্যের জন্য জিজ্ঞাসা করছেন, আপনি অন্য ব্যক্তিকে আপনাকে সহায়তা করা আরও কঠিন করে তুলছেন। এবং যদি এখন থেকে 6 মাস আগে আপনি এই কোডটি ডিবাগিং বা প্রসারিত করার কোনও সম্ভাবনা থাকে তবে আপনি সরাসরি নিজের জন্য আরও শক্ত করে তুলছেন।
cfg.yaml
): reldir : ../my/dir/
এবং থেকে একটি আপেক্ষিক পথ আমদানি করতে হবে reldir = cfg[reldir]
। তবে, এই অজগর কোডটি উইন্ডোজ এবং লিনাক্স উভয় ক্ষেত্রেই চলবে, বিভিন্ন অপারেটিং সিস্টেমের পাথ ডিভাইডারের সাথে সামঞ্জস্য করার জন্য আমার এটি প্রয়োজন; পারেন \\
বা /
। সুতরাং আমি reldir : os.path.join('..','my','dir')
কনফিগারেশন ফাইল ব্যবহার । তবে এটি কেবল reldir
এই আক্ষরিক স্ট্রিং হওয়ার ফলস্বরূপ , মূল্যায়ন করা হচ্ছে না, তাই আমি কোনও ফাইল খুলতে পারি না reldir
। তোমার কি কোন পরামর্শ আছে?
অন্যরা যেমন উল্লেখ করেছে, এটি "এক্সিকিউটিভ" ..
তবে, যদি আপনার কোডটিতে ভেরিয়েবল থাকে তবে আপনি এটি অ্যাক্সেস করতে "গ্লোবাল" ব্যবহার করতে পারেন, নিম্নলিখিত সংকেতটি উত্থাপন করতে সংকলককে আটকাতেও:
NameError: নাম 'p_variable' সংজ্ঞায়িত হয়নি
exec('p_variable = [1,2,3,4]')
global p_variable
print(p_variable)
এটি উল্লেখ করার মতো, আপনি যদি পাইথন ফাইলটি কল করতে চান তবে exec
সেই ভাইয়ের execfile
নামও রয়েছে। এটি কখনও কখনও ভাল যদি আপনি কোনও তৃতীয় পক্ষের প্যাকেজে কাজ করছেন যা ভয়ানক আইডিই অন্তর্ভুক্ত রয়েছে এবং আপনি তাদের প্যাকেজের বাইরে কোড করতে চান।
উদাহরণ:
execfile('/path/to/source.py)'
বা:
exec(open("/path/to/source.py").read())
ঠিক আছে .. আমি জানি এটি ঠিক কোনও উত্তর নয়, তবে সম্ভবত এটির মতো লোকদের জন্য দেখার জন্য একটি নোট। আমি বিভিন্ন ব্যবহারকারীর / গ্রাহকদের জন্য নির্দিষ্ট কোডটি কার্যকর করতে চেয়েছিলাম কিন্তু এক্সিকিউট / এভাল এড়াতেও চেয়েছিলাম। আমি প্রথমে প্রতিটি ব্যবহারকারীর জন্য একটি ডাটাবেসে কোড সংরক্ষণ এবং উপরেরটি করতে চেয়েছিলাম।
আমি একটি 'গ্রাহক_ ফিল্টারস' ফোল্ডারের মধ্যে ফাইল সিস্টেমে ফাইলগুলি তৈরি এবং 'গ্রাহক' মডিউলটি ব্যবহার করে শেষ করেছি, যদি সেই গ্রাহকের জন্য কোনও ফিল্টার প্রয়োগ না করা হয়, তবে এটি চালিয়ে গেছে
import imp
def get_customer_module(customerName='default', name='filter'):
lm = None
try:
module_name = customerName+"_"+name;
m = imp.find_module(module_name, ['customer_filters'])
lm = imp.load_module(module_name, m[0], m[1], m[2])
except:
''
#ignore, if no module is found,
return lm
m = get_customer_module(customerName, "filter")
if m is not None:
m.apply_address_filter(myobj)
সুতরাং গ্রাহক নাম = "জেজে" গ্রাহক_ফিলার্স apply jj_filter.py ফাইল থেকে প্রয়োগ_এড্রেস_ফিল্টার কার্যকর করবে