পাইথন ক্ষমা বনাম অনুমতি এবং হাঁসের টাইপিং


44

পাইথনে, আমি প্রায়শই শুনি যে "অনুমতি চাইতে" (টাইপ / শর্ত পরীক্ষা করা) পরিবর্তে "ক্ষমা প্রার্থনা" (ব্যতিক্রম ধরা) ভাল। পাইথনে হাঁসের টাইপিং প্রয়োগের ক্ষেত্রে, এটিই

try:
    x = foo.bar
except AttributeError:
    pass
else:
    do(x)

চেয়ে ভাল বা খারাপ

if hasattr(foo, "bar"):
    do(foo.bar)
else:
    pass

কর্মক্ষমতা, পাঠযোগ্যতা, "পাইথোনিক", বা অন্য কোনও গুরুত্বপূর্ণ বিষয়গুলির ক্ষেত্রে?


17
তৃতীয় বিকল্প রয়েছে, কিছু করবেন না এবং কোনও বার ছাড়াই কোনও
ফু

আমি শুনেছিলাম মনে করি hasattrযা অভ্যন্তরীণভাবে সঠিক চেষ্টা / ধরার সাথে বাস্তবায়িত হয়। এটি সত্য কিনা তা নিশ্চিত নয় ... (এটি সম্পত্তিগুলির উপর অন্যরকম আচরণ করবে, তাই না? সম্ভবত আমি ভাবছি getattr..)
ইজকাটা

@ ইজকাটা: এর বাস্তবায়নhasattr সি-এপিআই সমতুল্য getattr( Trueযদি সফল হয় তবে প্রত্যাবর্তন করুন False) ব্যবহার করে তবে সি-তে ব্যতিক্রমগুলি পরিচালনা করা অনেক দ্রুত is
মার্টিজন পিটারস

2
আমি মার্টিজানের উত্তর গ্রহণ করেছি, তবে আমি যুক্ত করতে চাই যে আপনি যদি কোনও বৈশিষ্ট্য নির্ধারণের চেষ্টা করছেন তবে আপনার অবশ্যই চেষ্টা / ধরার বিষয়টি বিবেচনা করা উচিত কারণ এটি সেটটার ছাড়াই সম্পত্তি হতে পারে, যে ক্ষেত্রে হ্যাশট্র সত্য হবে , তবে এটি এখনও অ্যাট্রিবিউটআরারের উত্থাপন করবে।
অন্ধকাররেখা

উত্তর:


60

এটি সত্যিই নির্ভর করে যে আপনি কীভাবে ব্যতিক্রমটি নিক্ষেপ করতে চলেছেন often

দুটি মতামতই আমার মতে, সমানভাবে বৈধ, কমপক্ষে পাঠযোগ্যতার এবং পাইথোনিক-নেসের ক্ষেত্রে। তবে যদি আপনার 90% অবজেক্টের বৈশিষ্ট্য না থাকে তবে barআপনি দুটি পদ্ধতির মধ্যে একটি পৃথক পারফরম্যান্সের পার্থক্য লক্ষ্য করবেন:

>>> import timeit
>>> def askforgiveness(foo=object()):
...     try:
...         x = foo.bar
...     except AttributeError:
...         pass
... 
>>> def askpermission(foo=object()):
...     if hasattr(foo, 'bar'):
...         x = foo.bar
... 
>>> timeit.timeit('testfunc()', 'from __main__ import askforgiveness as testfunc')
2.9459929466247559
>>> timeit.timeit('testfunc()', 'from __main__ import askpermission as testfunc')
1.0396890640258789

কিন্তু যদি আপনার বস্তুর 90% না অ্যাট্রিবিউট আছে, টেবিল পরিণত করা হয়েছে:

>>> class Foo(object):
...     bar = None
... 
>>> foo = Foo()
>>> timeit.timeit('testfunc(foo)', 'from __main__ import askforgiveness as testfunc, foo')
0.31336188316345215
>>> timeit.timeit('testfunc(foo)', 'from __main__ import askpermission as testfunc, foo')
0.4864199161529541

সুতরাং, পারফরম্যান্সের দৃষ্টিকোণ থেকে আপনার এমন পরিস্থিতি বেছে নিতে হবে যা আপনার পরিস্থিতিতে সবচেয়ে ভাল কাজ করে।

শেষ পর্যন্ত, timeitমডিউলটির কিছু কৌশলগত ব্যবহার আপনার পক্ষে করা সর্বাধিক পাইথোনিক জিনিস হতে পারে।


1
কয়েক সপ্তাহ আগে আমি এই প্রশ্নটি জিজ্ঞাসা করেছি: প্রোগ্রামার্স.স্ট্যাকেক্সেক্সঞ্জ / প্রশ্নগুলি / ১17১9 8 /… সেখানে আমি জিজ্ঞাসা করেছি যে শিথিলভাবে টাইপ করা ভাষায় আপনার অতিরিক্ত ধরণের চেক করা উচিত ছিল, এবং লোকেরা আমাকে বোমা মেরে বলেছিল যে আপনি না বলেছিলেন। আমি আপনাকে দেখতে জানি।
তুলিনাস কর্ডোভা

@ ইউজার1598390: আপনি যখন এমন একটি এপিআই সংজ্ঞায়িত করেন যা ধরণের একজাতীয় মিশ্রণের প্রত্যাশা করে তখন আপনাকে কিছু পরীক্ষা করতে হবে। বেশিরভাগ সময়, আপনি না। এটি সুনির্দিষ্ট অঞ্চল যা থেকে আপনি সামগ্রিকভাবে দৃষ্টান্তগুলি সম্পর্কে নিয়মগুলি অর্জন করতে পারবেন না, আমি ভীত।
মার্টিজন পিটারস

ভাল, যে কোনও গুরুতর সিস্টেম বিকাশ একটি এপিআই সংজ্ঞায়িত জড়িত। সুতরাং আমি অনুমান করি যে কড়া ভাষাগুলি এর জন্য সবচেয়ে ভাল কারণ আপনাকে কম কোড করতে হবে যেহেতু সংকলকটি সংকলনের সময় আপনার জন্য প্রকারগুলি পরীক্ষা করে।
তুলিনাস কর্ডোভা

1
@ গ্যারেথরিস: এটি উত্তরটির উত্তরার অর্ধেকের জন্য একটি প্যাটার্ন স্থাপন করে যেখানে আমি কার্য-অধীনে-পরীক্ষার পক্ষে একটি যুক্তিতে পাস করি।
মার্টিজন পিটারস 16

1
মনে রাখবেন যে hasattrএটি আসলে হুডের নীচে ব্যতীত সি-এপিআই সমান চেষ্টা করে, যেহেতু এটি পাইথনের কোনও অ্যাট্রিবিউট আছে কি না তা নির্ধারণের একমাত্র সাধারণ উপায়টি এটি অ্যাক্সেস করার চেষ্টা করে।
ব্যবহারকারী 2357112

11

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

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


3

পারফরম্যান্স, আমার মনে হয়, এটি একটি গৌণ উদ্বেগ। যদি এটি দেখা দেয় তবে একজন প্রোফাইলার আপনাকে আসল বাধাগুলিতে মনোনিবেশ করতে সহায়তা করবে, যা আপনি সম্ভাব্য অবৈধ যুক্তিগুলির সাথে কীভাবে আচরণ করেন বা নাও হতে পারে।

অন্যদিকে পঠনযোগ্যতা এবং সরলতা সর্বদা একটি প্রধান উদ্বেগ। এখানে কোনও কঠোর নিয়ম নেই, কেবল আপনার রায় ব্যবহার করুন।

এটি সর্বজনীন সমস্যা, তবে পরিবেশ- বা ভাষা-নির্দিষ্ট সম্মেলনগুলি প্রাসঙ্গিক। উদাহরণস্বরূপ, পাইথন-এ সাধারণত আপনার প্রত্যাশিত বৈশিষ্ট্যটি ব্যবহার করা এবং কোনও সম্ভাব্য অ্যাট্রিবিউটরর কলকারীর কাছে পৌঁছে দেওয়া সহজ হয়।


-1

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


3
আপনার উত্তর ইতিমধ্যে অন্যদের দ্বারা যা বলেছে তার চেয়ে বেশি কিছু যোগ করে না। অন্যান্য সাইটের মতো নয়, প্রোগ্রামাররা এমন উত্তর প্রত্যাশা করে যা উত্তরের পিছনে কেন তা ব্যাখ্যা করে । আপনি নীরব ব্যর্থতার ইস্যুটির সাথে একটি ভাল বক্তব্য স্পর্শ করেছেন, তবে অবশ্যই এটির জন্য ন্যায়বিচার সরবরাহ করবেন না। নিম্নলিখিতটি পড়তে সহায়তা করতে পারে: প্রোগ্রামার্স.স্ট্যাকেক্সেক্সঞ্জ.

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