আমি পাইথনে যে বইটি পড়ছি, তাতে কোডটি ব্যবহার করা যায় eval(input('blah'))
আমি ডকুমেন্টেশনটি পড়েছি এবং আমি এটি বুঝতে পারি, তবে এটি কীভাবে input()
ফাংশনটি পরিবর্তন করে তা আমি এখনও দেখতে পাই না ।
এটার কাজ কি? কেউ কি ব্যাখ্যা করতে পারেন?
আমি পাইথনে যে বইটি পড়ছি, তাতে কোডটি ব্যবহার করা যায় eval(input('blah'))
আমি ডকুমেন্টেশনটি পড়েছি এবং আমি এটি বুঝতে পারি, তবে এটি কীভাবে input()
ফাংশনটি পরিবর্তন করে তা আমি এখনও দেখতে পাই না ।
এটার কাজ কি? কেউ কি ব্যাখ্যা করতে পারেন?
উত্তর:
ইভাল ফাংশনটি একটি পাইথন প্রোগ্রামকে নিজের মধ্যে পাইথন কোড চালাতে দেয়।
উদাহরণস্বরূপ (ইন্টারেক্টিভ শেল):
>>> x = 1
>>> eval('x + 1')
2
>>> eval('x')
1
eval()
উচ্চ-গতিশীল কোডটি কার্যকর করতেও ব্যবহার করা যেতে পারে তবে এটি ব্যবহারের আগে আপনার নিজের সুরক্ষা এবং সম্পাদনের ঝুঁকি সম্পর্কে পুরোপুরি সচেতন হওয়া উচিত make
eval
, বা এটি যা করতে পারে তা করতে পারে না eval
।
eval
, অনিরাপদ হওয়া ব্যতীত কোডেপ্যাডের মতো পুরো প্রোগ্রাম চালাতে পারে না কারণ এটি কেবলমাত্র একটি একক অভিব্যক্তিকে মূল্যায়ন করতে পারে।
eval()
একটি স্ট্রিংকে কোড হিসাবে ব্যাখ্যা করে। এত লোক আপনাকে এটি ব্যবহার সম্পর্কে সতর্ক করার কারণ হ'ল কোনও ব্যবহারকারী কম্পিউটারে কোড চালনার বিকল্প হিসাবে এটি ব্যবহার করতে পারেন। আপনি যদি আমদানি eval(input())
এবং os
আমদানি করেন তবে কোনও ব্যক্তি এতে টাইপ করতে পারে input()
os.system('rm -R *')
যা আপনার হোম ডিরেক্টরিতে আপনার সমস্ত ফাইল মুছবে। (ধরে নিচ্ছি আপনার ইউনিক্স সিস্টেম রয়েছে)। ব্যবহার eval()
করা একটি সুরক্ষা গর্ত is আপনার যদি স্ট্রিংগুলিকে অন্য ফর্ম্যাটে রূপান্তর করতে হয় তবে এমন জিনিসগুলি ব্যবহার করার চেষ্টা করুন যা পছন্দ করে int()
।
eval
সঙ্গে input()
একটি নিরাপত্তা গর্ত হয়। input()
একটি খোলামেলা বিবৃতি ভিতরে রাখবেন না এবং আপনি ভাল থাকবেন।
eval
অনেক ক্ষেত্রে সুরক্ষার বিষয়টিও তাই ।
input
সাধারণত কনসোল থেকে তার ডেটা নেওয়া হয় ব্যবহারকারী কেবল প্রোগ্রামটি থেকে বেরিয়ে rm -R *
যেভাবেই টাইপ করতে পারত ...
এখানে প্রচুর ভাল উত্তর দেওয়া হয়েছে, তবে eval()
এর globals
ও locals
কাওয়ার্গগুলির প্রসঙ্গে কেউ এর ব্যবহারের বর্ণনা দেয় না , অর্থাৎ eval(expression, globals=None, locals=None)
( eval
এখানে ডক্স দেখুন )।
এই ফাংশন মাধ্যমে উপলব্ধ ফাংশন সীমাবদ্ধ করতে ব্যবহার করা যেতে পারে eval
। উদাহরণস্বরূপ, আপনি যদি একটি নতুন অজগর দোভাষী লোড করেন locals()
এবং globals()
এটি একই হয় এবং এটির মতো দেখতে কিছু:
>>>globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
'__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
'__package__': None, '__name__': '__main__'}
builtins
মডিউলটির মধ্যে অবশ্যই ফাংশন রয়েছে যা কোনও সিস্টেমের উল্লেখযোগ্য ক্ষতি করতে পারে। তবে যে কোনও কিছু এবং আমরা চাই না এমন সমস্ত কিছু অবরুদ্ধ করা সম্ভব। একটি উদাহরণ নেওয়া যাক। বলুন আমরা সিস্টেমে উপলব্ধ কোরগুলির একটি ডোমেন উপস্থাপনের জন্য একটি তালিকা তৈরি করতে চাই। আমার জন্য আমার কাছে 8 টি কোর রয়েছে তাই আমি একটি তালিকা চাই [1, 8]
।
>>>from os import cpu_count
>>>eval('[1, cpu_count()]')
[1, 8]
তেমনি সমস্ত __builtins__
পাওয়া যায়।
>>>eval('abs(-1)')
1
ঠিক আছে. সুতরাং সেখানে আমরা একটি ফাংশন দেখতে পাচ্ছি যা আমরা উন্মুক্ত করতে চাই এবং এর একটি উদাহরণ (অনেকের মধ্যে অনেক বেশি জটিল হতে পারে) পদ্ধতিটি আমরা প্রকাশ করতে চাই না। সুতরাং আসুন সব ব্লক করা যাক।
>>>eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable
আমরা কার্যকরভাবে সমস্ত ব্লক করেছি __builtins__
ক্রিয়াকলাপ এবং এর ফলে আমাদের সিস্টেমে সুরক্ষা একটি স্তর নিয়ে এসেছে। এই মুহুর্তে আমরা ফাংশনগুলিতে আবার যুক্ত করতে শুরু করতে পারি যা আমরা প্রকাশ করতে চাই না।
>>>from os import cpu_count
>>>exposed_methods = {'cpu_count': cpu_count}
>>>eval('cpu_count()', {'__builtins__':None}, exposed_methods)
8
>>>eval('abs(cpu_count())', {'__builtins__':None}, exposed_methods)
TypeError: 'NoneType' object is not subscriptable
আমরা cpu_count
চাই না এমন সমস্ত কিছু আটকে রেখে এখন আমাদের কাছে ফাংশনটি উপলব্ধ রয়েছে। আমার মতে, এটি অত্যন্ত কার্যকর এবং অন্যান্য উত্তরগুলির পরিধি থেকে স্পষ্টতই, একটি সাধারণ বাস্তবায়ন নয়। এর মতো কোনও কিছুর জন্য অসংখ্য ব্যবহার রয়েছে এবং যতক্ষণ না এটি সঠিকভাবে পরিচালিত হয় ততক্ষণ আমি ব্যক্তিগতভাবে অনুভব করিeval
নিরাপদে দুর্দান্ত মান হিসাবে ব্যবহার করা যেতে পারে বলে ।
বিশেষ দ্রষ্টব্য
এগুলি সম্পর্কে শীতল কিছু অন্যটি হ'ল kwargs
আপনি আপনার কোডের জন্য শর্টহ্যান্ড ব্যবহার করতে শুরু করতে পারেন। ধরা যাক আপনি কিছু আমদানি করা পাঠ্য কার্যকর করতে পাইপলাইনের অংশ হিসাবে ইওল ব্যবহার করেন। পাঠ্যের সঠিক কোড থাকা দরকার নেই, এটি কিছু টেমপ্লেট ফাইল ফর্ম্যাট অনুসরণ করতে পারে এবং আপনার পছন্দসই কিছু কার্যকর করতে পারে। উদাহরণ স্বরূপ:
>>>from os import cpu_count
>>>eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]
পাইথন ২.x input(...)
এর সমান eval(raw_input(...))
, পাইথনের ৩.x এর raw_input
নামকরণ করা হয়েছিল input
, যা আমি সন্দেহ করি যা আপনার বিভ্রান্তির দিকে নিয়ে যায় (আপনি সম্ভবত input
পাইথন ২.x এর জন্য নথির দিকে তাকিয়ে ছিলেন )। অতিরিক্ত হিসাবে, eval(input(...))
পাইথন 3.x এ সূক্ষ্মভাবে কাজ করবে তবে TypeError
পাইথন 2 এ একটি উত্থাপন করবে ।
এই ক্ষেত্রে eval
স্ট্রিং থেকে প্রত্যাগত নিগৃহীত করতে ব্যবহৃত হয় input
একটি অভিব্যক্তি মধ্যে এবং বুঝিয়ে দিলেন। সাধারণত এটি খারাপ অভ্যাস হিসাবে বিবেচিত হয়।
input
অর্থ কী raw_input
২.x.
একটি লাইন পড়ার এবং ব্যাখ্যা করার একটি বিভ্রান্তিকর উদাহরণ হতে পারে।
চেষ্টা করুন eval(input())
এবং টাইপ করুন "1+1"
- এটি মুদ্রণ করা উচিত 2
। ইভাল এক্সপ্রেশন মূল্যায়ন।
eval()
পাইথন এক্সপ্রেশন হিসাবে পাস করা স্ট্রিংকে মূল্যায়ন করে ফলাফলটি দেয়। উদাহরণ স্বরূপ,eval("1 + 1")
ব্যাখ্যা এবং এক্সপ্রেশন এক্সপ্রেশন"1 + 1"
এবং ফলাফল প্রদান করে (2)।
আপনি বিভ্রান্ত হওয়ার একটি কারণ হ'ল আপনি যে কোডটি উদ্ধৃত করেছেন তাতে একটি স্তর নির্দেশনা জড়িত। অভ্যন্তরীণ ফাংশন কল (ইনপুট) প্রথমে কার্যকর করা হয় যাতে ব্যবহারকারী "ব্লাহ" প্রম্পটটি দেখেন। আসুন কল্পনা করুন যে তারা "1 + 1" (স্পষ্টতার জন্য উদ্ধৃতি যুক্ত হয়েছে, আপনার প্রোগ্রামটি চালনার সময় এগুলি টাইপ করবেন না) দিয়ে প্রতিক্রিয়া জানায়, ইনপুট ফাংশনটি সেই স্ট্রিংটি ফেরত দেয় যা তারপরে বাইরের ফাংশনে (ইওল) পাস হয় যা স্ট্রিংটির ব্যাখ্যা করে এবং ফলাফল প্রদান (2)।
এখানে eval সম্পর্কে আরও পড়ুন ।
eval()
নামটি যেমন প্রস্তাবিত হয় তত্ক্ষণিত যুক্তিটি মূল্যায়ন করে।
raw_input()
input()
পাইথন 3.x সংস্করণে এখন । সুতরাং এর ব্যবহারের জন্য সর্বাধিক সন্ধান পাওয়া উদাহরণ eval()
হ'ল input()
পাইথনের ২.x সংস্করণে কার্যকারিতা সরবরাহ করার জন্য এটির ব্যবহার । কাঁচা-ইনপুট ব্যবহারকারী-প্রবেশ করা ডেটাটিকে স্ট্রিং হিসাবে ফিরিয়ে দেয়, যখন ইনপুট প্রবেশ করা তথ্যের মূল্য নির্ধারণ করে তা ফেরত দেয়।
eval(input("bla bla"))
এইভাবে input()
2.x এর কার্যকারিতাটির প্রতিলিপি করে , অর্থাত্, ব্যবহারকারী-প্রবেশ করা ডেটা মূল্যায়নের।
সংক্ষেপে: eval()
এটিতে দেওয়া আর্গুমেন্টগুলি মূল্যায়ন করে এবং তাই eval('1 + 1')
2 ফিরে এসেছে।
এর দরকারী অ্যাপ্লিকেশনগুলির মধ্যে একটি eval()
হ'ল স্ট্রিং থেকে পাইথন এক্সপ্রেশনকে মূল্যায়ন করা। উদাহরণস্বরূপ ফাইল স্ট্রিং উপস্থাপনা থেকে লোড করুন:
running_params = {"Greeting":"Hello "}
fout = open("params.dat",'w')
fout.write(repr(running_params))
fout.close()
এটি পরিবর্তনশীল হিসাবে পড়ুন এবং এটি সম্পাদনা করুন:
fin = open("params.dat",'r')
diction=eval(fin.read())
diction["Greeting"]+="world"
fin.close()
print diction
আউটপুট:
{'Greeting': 'Hello world'}
eval
করে?
আমি এই প্রশ্নের উত্তর দিতে দেরি করছি কিন্তু, কেউই প্রশ্নের সুস্পষ্ট উত্তর দেবে বলে মনে হচ্ছে না।
যদি কোনও ব্যবহারকারী একটি সংখ্যার মান প্রবেশ করে তবে input()
একটি স্ট্রিং প্রদান করবে।
>>> input('Enter a number: ')
Enter a number: 3
>>> '3'
>>> input('Enter a number: ')
Enter a number: 1+1
'1+1'
সুতরাং, eval()
প্রত্যাবর্তিত মান (বা অভিব্যক্তি) যা একটি স্ট্রিং এবং রিটার্ন পূর্ণসংখ্যা / ভাসা মূল্যায়ন করবে।
>>> eval(input('Enter a number: '))
Enter a number: 1+1
2
>>>
>>> eval(input('Enter a number: '))
Enter a number: 3.14
3.14
উত্স সম্পর্কে এটি একটি খারাপ অনুশীলন। int()
বা এই ক্ষেত্রে float()
পরিবর্তে ব্যবহার করা উচিত eval()
।
>>> float(input('Enter a number: '))
Enter a number: 3.14
3.14
আপনি যদি মূল্যায়ন স্ট্রিংটিকে সাধারণ আক্ষরিক মধ্যে সীমাবদ্ধ করতে চান তবে অন্য একটি বিকল্পটি হ'ল ব্যবহার করা ast.literal_eval()
। কিছু উদাহরণ:
import ast
# print(ast.literal_eval('')) # SyntaxError: unexpected EOF while parsing
# print(ast.literal_eval('a')) # ValueError: malformed node or string
# print(ast.literal_eval('import os')) # SyntaxError: invalid syntax
# print(ast.literal_eval('1+1')) # 2: but only works due to a quirk in parser
# print(ast.literal_eval('1*1')) # ValueError: malformed node or string
print(ast.literal_eval("{'a':1}")) # {'a':1}
দস্তাবেজগুলি থেকে :
একটি এক্সপ্রেশন নোড বা পাইথন আক্ষরিক বা ধারক প্রদর্শনযুক্ত স্ট্রিং নিরাপদে মূল্যায়ন করুন। সরবরাহ করা স্ট্রিং বা নোড কেবলমাত্র পাইথনের আক্ষরিক কাঠামোগুলি থাকতে পারে: স্ট্রিং, বাইটস, সংখ্যা, টিপলস, তালিকা, ডিক্টস, সেটস, বুলিয়ান এবং কিছুই নয়।
এটি নিরাপদে মূল্যবোধকে বিশ্লেষণ না করে অবিশ্বস্ত উত্স থেকে পাইথন মানযুক্ত স্ট্রিংগুলি নিরাপদে মূল্যায়নের জন্য ব্যবহার করা যেতে পারে। এটি নির্বিচারে জটিল অভিব্যক্তিগুলির মূল্যায়ন করতে সক্ষম নয় , উদাহরণস্বরূপ অপারেটরদের জড়িত বা ইনডেক্সিং।
কেন এটি এত সীমিত, মেলিং তালিকা থেকে :
আক্ষরিক সাথে অপারেটর এক্সপ্রেশন মঞ্জুরি দেওয়া সম্ভব, তবে বর্তমান বাস্তবায়নের চেয়ে অনেক জটিল। একটি সাধারণ বাস্তবায়ন নিরাপদ নয়: আপনি মূলত আনবাউন্ডেড সিপিইউ এবং মেমরির ব্যবহার কোনও প্রচেষ্টা ছাড়াই প্ররোচিত করতে পারেন ("9 ** 9 ** 9" বা "[কিছুই নয়] * 9 ** 9" চেষ্টা করুন)।
দরকারীতার হিসাবে, এই ফাংশনটি রিটার () দ্বারা স্ট্রিংযুক্ত হিসাবে আক্ষরিক মান এবং পাত্রে "রিড রিড" উপযোগী। এটি উদাহরণস্বরূপ জেএসএনের চেয়ে বেশি শক্তিশালী এমন ফর্ম্যাটে সিরিয়ালাইজেশনের জন্য ব্যবহার করা যেতে পারে।
ast.literal_eval
আপনার '1+1'
উদাহরণের বিপরীতে অপারেটরদের সমর্থন করে না । তবুও এটি সমর্থন তালিকা, সংখ্যা, স্ট্রিং ইত্যাদি করে এবং তাই সাধারণ eval
ব্যবহারের ক্ষেত্রে এটি একটি ভাল বিকল্প ।