পাইথনে পুরাতন স্টাইল এবং নতুন স্টাইলের ক্লাসগুলির মধ্যে পার্থক্য কী? আমি কখন এক বা অন্যটি ব্যবহার করব?
পাইথনে পুরাতন স্টাইল এবং নতুন স্টাইলের ক্লাসগুলির মধ্যে পার্থক্য কী? আমি কখন এক বা অন্যটি ব্যবহার করব?
উত্তর:
থেকে নতুন স্টাইলের এবং ক্লাসিক শ্রেণীর :
পাইথন ২.১ অবধি, পুরানো স্টাইলের ক্লাসগুলি কেবলমাত্র ব্যবহারকারীর জন্য উপলব্ধ স্বাদ ছিল।
(পুরোনো শৈলী) ক্লাসের ধারণা ধরনের ধারণা থেকে সম্পর্কহীন: যদি
x
একটি পুরানো ধাঁচের ক্লাসের একটা নিদর্শন হয়, তাহলেx.__class__
বর্গ designatesx
কিন্তুtype(x)
সর্বদা<type 'instance'>
।এটি এই সত্যটি প্রতিফলিত করে যে সমস্ত পুরানো-শৈলীর দৃষ্টান্তগুলি, তাদের শ্রেণীর স্বতন্ত্রভাবে, উদাহরণস্বরূপ বলা হয় একটি একক অন্তর্নির্মিত টাইপের সাথে বাস্তবায়িত।
ক্লাস এবং প্রকারের ধারণাগুলি একত্রিত করার জন্য পাইথন ২.২ এ নতুন-স্টাইলের ক্লাস চালু করা হয়েছিল । একটি নতুন-শৈলীর শ্রেণিটি কেবল একটি ব্যবহারকারী-সংজ্ঞায়িত প্রকার, আর কোনও, কম নয়।
যদি এক্স কোনও নতুন-স্টাইলের শ্রেণীর উদাহরণ, তবে
type(x)
সাধারণত এটি একই রকম হয়x.__class__
(যদিও এটির নিশ্চয়তা নেই - একটি নতুন-শৈলিক শ্রেণীর উদাহরণটি এর জন্য ফেরত মানকে ওভাররাইড করার অনুমতি দেয়x.__class__
)।নতুন-স্টাইলের ক্লাস চালু করার জন্য প্রধান প্রেরণা হল একটি সম্পূর্ণ মেটা-মডেল সহ ইউনিফাইড অবজেক্ট মডেল সরবরাহ করা ।
এটিতে বেশ কয়েকটি তাত্ক্ষণিক সুবিধাও রয়েছে যেমন সর্বাধিক অন্তর্নির্মিত ধরণের সাবক্লাস করার ক্ষমতা বা "বর্ণনাকারী" প্রবর্তন যেমন গণিত বৈশিষ্ট্য সক্ষম করে।
উপযুক্ততা কারণে, ক্লাস এখনো ডিফল্টরূপে পুরোনো শৈলী হয় ।
নতুন স্টাইলের ক্লাসগুলি অন্য নতুন-স্টাইলের ক্লাসকে (অর্থাত্ একটি টাইপ) প্যারেন্ট ক্লাস হিসাবে নির্দিষ্ট করে তৈরি করা হয় বা অন্য কোনও পিতামাতার প্রয়োজন না হলে "শীর্ষ-স্তরের প্রকার" অবজেক্টটি তৈরি করা হয়।
নতুন ধাঁচের ক্লাসগুলির আচরণটি বিভিন্ন ধরণের পুরানো স্টাইলের ক্লাসগুলির সাথে বিভিন্ন ধরণের গুরুত্বপূর্ণ বিবরণে পৃথক হয় যা কি ধরণের রিটার্ন দেয়।
এই কয়েকটি পরিবর্তন নতুন অবজেক্ট মডেলের জন্য মৌলিক, যেমন বিশেষ পদ্ধতিগুলি ডাকা হয়। অন্যগুলি "সংশোধন" যা একাধিক উত্তরাধিকারের ক্ষেত্রে পদ্ধতি সমাধানের আদেশের মতো সামঞ্জস্যতার উদ্বেগগুলির জন্য আগে প্রয়োগ করা যায়নি।
পাইথন 3-এ কেবল নতুন-স্টাইলের ক্লাস রয়েছে ।
আপনি সাবক্লাস থেকে সাবক্লাস করেছেন কিনা তা বিবেচনাধীন
object
নয়, ক্লাসগুলি পাইথন 3-এ নতুন-স্টাইল।
super()
পুরানো স্টাইলের ক্লাসে কাজ না করার মতো কয়েকটি বৈশিষ্ট্য । উল্লেখ করার মতো নয়, যেমনটি এই নিবন্ধটি বলেছে, এখানে এমআরওর মতো মৌলিক সংশোধন এবং বিশেষ পদ্ধতি রয়েছে যা এটি ব্যবহারের ভাল কারণের চেয়ে বেশি।
ঘোষণা-অনুযায়ী:
নতুন স্টাইলের ক্লাসগুলি অবজেক্ট থেকে বা অন্য নতুন স্টাইলের ক্লাস থেকে উত্তরাধিকারী ।
class NewStyleClass(object):
pass
class AnotherNewStyleClass(NewStyleClass):
pass
পুরাতন স্টাইলের ক্লাস হয় না।
class OldStyleClass():
pass
পাইথন 3 দ্রষ্টব্য:
পাইথন 3 পুরানো শৈলীর ক্লাস সমর্থন করে না, সুতরাং উপরের ফলাফলগুলি একটি নতুন-শৈলীর শ্রেণিতে উল্লিখিত হয়।
object
।
class AnotherOldStyleClass: pass
class A: pass
এবং class A(): pass
এটি কঠোর সমতুল্য। প্রথম মানে "একজন কোনো পিতা বা মাতা ক্লাসের উত্তরাধিকারী নেই" এবং দ্বিতীয় উপায়ে "কোন পিতা বা মাতা শ্রেণীর উত্তরাধিকারী" । এটি বেশ একইরকম not is
এবংis not
পুরানো এবং নতুন স্টাইলের ক্লাসগুলির মধ্যে গুরুত্বপূর্ণ আচরণের পরিবর্তন
Exception
(নীচে উদাহরণস্বরূপ)__slots__
যোগএটি অন্যান্য উত্তরে উল্লিখিত ছিল, তবে এখানে ক্লাসিক এমআরও এবং সি 3 এমআরও (নতুন স্টাইলের ক্লাসে ব্যবহৃত) এর মধ্যে পার্থক্যের একটি দৃ .় উদাহরণ পাওয়া যায়।
প্রশ্নটি এমন ক্রম যা ক্রমযুক্ত বৈশিষ্ট্যগুলিতে (যার মধ্যে পদ্ধতি এবং সদস্য ভেরিয়েবলগুলি অন্তর্ভুক্ত) একাধিক উত্তরাধিকারে অনুসন্ধান করা হয়।
ক্লাসিক ক্লাসগুলি বাম থেকে ডানে গভীরতার প্রথম অনুসন্ধান করে। প্রথম ম্যাচে থামুন। তাদের __mro__
বৈশিষ্ট্য নেই।
class C: i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass
assert C12().i == 0
assert C21().i == 2
try:
C12.__mro__
except AttributeError:
pass
else:
assert False
নতুন স্টাইলের ক্লাস এমআরও একক ইংরেজী বাক্যে সংশ্লেষ করা আরও জটিল। এটি বিস্তারিতভাবে এখানে ব্যাখ্যা করা হয় । এর বৈশিষ্ট্যগুলির মধ্যে একটি হ'ল একটি বেস ক্লাস কেবল তার সমস্ত উত্পন্ন ক্লাস হয়ে গেলেই অনুসন্ধান করা হয়। তাদের __mro__
বৈশিষ্ট্য রয়েছে যা অনুসন্ধানের ক্রমটি দেখায়।
class C(object): i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass
assert C12().i == 2
assert C21().i == 2
assert C12.__mro__ == (C12, C1, C2, C, object)
assert C21.__mro__ == (C21, C2, C1, C, object)
Exception
পাইথনের আশেপাশে 2.5 টি অনেক ক্লাস করা যায় এবং পাইথন ২.6 এর আশেপাশে এটি সরানো হয়েছিল। পাইথন ২.7.৩ এ:
# OK, old:
class Old: pass
try:
raise Old()
except Old:
pass
else:
assert False
# TypeError, new not derived from `Exception`.
class New(object): pass
try:
raise New()
except TypeError:
pass
else:
assert False
# OK, derived from `Exception`.
class New(Exception): pass
try:
raise New()
except New:
pass
else:
assert False
# `'str'` is a new style object, so you can't raise it:
try:
raise 'str'
except TypeError:
pass
else:
assert False
পুরানো শৈলীর শ্রেণীর বৈশিষ্ট্যগুলি অনুসন্ধানের জন্য এখনও সামান্য দ্রুত faster এটি সাধারণত গুরুত্বপূর্ণ নয়, তবে এটি পারফরম্যান্স-সংবেদনশীল পাইথন ২.x কোডে কার্যকর হতে পারে:
[3] এ: ক্লাস এ: ...: Def __init __ (স্ব): ...: self.a = 'হাই সেখানে' ...: [4] এ: শ্রেণি বি (অবজেক্ট): ...: Def __init __ (স্ব): ...: self.a = 'হাই সেখানে' ...: []] এ: অওবজ = এ () [7] এ: ববজ = বি () [8] এ:% সময়কাল aobj.a 10000000 লুপ, লুপ প্রতি 3: 78.7 এনএস এর মধ্যে সেরা [10] এ:% টাইমাইট ববজ.এ 10000000 লুপ, প্রতি লুপে 3: 86.9 এনএসের মধ্যে সেরা
%timeit aobj.a
10000000 loops, best of 3: 66.1 ns per loop
%timeit bobj.a
10000000 loops, best of 3: 53.9 ns per loop
গাইডো ইনসাইট স্টোরি অন নিউ-স্টাইল ক্লাস লিখেছেন , এটি পাইথনের নতুন স্টাইল এবং পুরানো স্টাইলের ক্লাস সম্পর্কে সত্যই দুর্দান্ত একটি নিবন্ধ।
পাইথন 3-এ কেবল নতুন-স্টাইলের ক্লাস রয়েছে। এমনকি যদি আপনি একটি 'পুরানো-শৈলীর ক্লাস' লিখেন তবে তা স্পষ্টতই উত্পন্ন object
।
নতুন স্টাইলের ক্লাসগুলিতে কিছু উন্নত বৈশিষ্ট্য রয়েছে পুরানো-শৈলীর ক্লাসগুলির অভাবে, যেমন super
, নতুন সি 3 এমআরও , কিছু জাদুকরী পদ্ধতি ইত্যাদি have
এখানে একটি খুব ব্যবহারিক, সত্য / মিথ্যা পার্থক্য। নিম্নলিখিত কোডের দুটি সংস্করণের মধ্যে একমাত্র পার্থক্য হ'ল দ্বিতীয় সংস্করণে ব্যক্তি বস্তু থেকে উত্তরাধিকার সূত্রে আসে । তা ছাড়া, দুটি সংস্করণ অভিন্ন, তবে বিভিন্ন ফলাফল সহ:
পুরানো শৈলী ক্লাস
class Person():
_names_cache = {}
def __init__(self,name):
self.name = name
def __new__(cls,name):
return cls._names_cache.setdefault(name,object.__new__(cls,name))
ahmed1 = Person("Ahmed")
ahmed2 = Person("Ahmed")
print ahmed1 is ahmed2
print ahmed1
print ahmed2
>>> False
<__main__.Person instance at 0xb74acf8c>
<__main__.Person instance at 0xb74ac6cc>
>>>
নতুন ধাঁচের ক্লাস
class Person(object):
_names_cache = {}
def __init__(self,name):
self.name = name
def __new__(cls,name):
return cls._names_cache.setdefault(name,object.__new__(cls,name))
ahmed1 = Person("Ahmed")
ahmed2 = Person("Ahmed")
print ahmed2 is ahmed1
print ahmed1
print ahmed2
>>> True
<__main__.Person object at 0xb74ac66c>
<__main__.Person object at 0xb74ac66c>
>>>
_names_cache
এমন একটি অভিধান যা আপনার প্রতিটি নামকে ক্যাশে করে (ভবিষ্যতের পুনরুদ্ধারের জন্য স্টোর) Person.__new__
। সেটডিফল্ট পদ্ধতি (যে কোনও অভিধানে সংজ্ঞায়িত) দুটি আর্গুমেন্ট নেয়: একটি কী এবং একটি মান। কীটি ডিকটিতে থাকলে, এটির মান ফিরে আসবে। যদি এটি ডিকের মধ্যে না থাকে তবে এটি প্রথমে দ্বিতীয় আর্গুমেন্ট হিসাবে পাস হওয়া মানকে সেট করবে এবং তারপরে এটি ফিরিয়ে দেবে।
__new__()
সর্বদা ডাকা হয় এবং এটি সর্বদা একটি নতুন অবজেক্ট তৈরি করে এবং তারপরে নিক্ষেপ করে। if
এক্ষেত্রে একটি ভাল হয় .setdefault()
।
__new__
পুরানো স্টাইলের ক্লাসগুলির পক্ষে আসলে জিনিস নয়, এটি উদাহরণস্বরূপ নির্মাণে ব্যবহৃত হয় না (এটি কেবল একটি র্যান্ডম নাম যা বিশেষ দেখতে যেমন সংজ্ঞাযুক্ত __spam__
)। সুতরাং পুরানো-শৈলীর শ্রেণিটি তৈরি করা কেবলমাত্র আহ্বান জানায় __init__
, যখন নতুন শৈলীর নির্মাণগুলি __new__
(নাম অনুসারে সিঙ্গলটন উদাহরণে কোয়েলসেসিং) নির্মাণ এবং __init__
এটি আরম্ভ করার আহ্বান জানায় ।
নতুন-স্টাইলের ক্লাসগুলি উত্তরাধিকার সূত্রে প্রাপ্ত object
এবং পাইথন ২.২ এর পরে অবশ্যই (যেমনটি class Classname(object):
পরিবর্তে class Classname:
) লেখা উচিত । মূল পরিবর্তনটি হ'ল ধরণ এবং শ্রেণী একত্রিত করা এবং এর দুর্দান্ত পার্শ্ব-প্রতিক্রিয়া হ'ল এটি আপনাকে বিল্ট-ইন টাইপগুলি থেকে উত্তরাধিকারী করার অনুমতি দেয়।
আরও তথ্যের জন্য ডেস্ক্রিন্ট্রো পড়ুন ।
নতুন স্টাইলের ক্লাসগুলি super(Foo, self)
যেখানে Foo
ক্লাস এবং self
এটি উদাহরণ হিসাবে ব্যবহার করতে পারে ।
super(type[, object-or-type])
এমন কোনও প্রক্সি অবজেক্ট ফেরত করুন যা পিতামাতাকে বা ভাইবোনের ধরণের শ্রেণিতে পদ্ধতি কল করে। এটি উত্তরাধিকার সূত্রে প্রাপ্ত পদ্ধতিগুলিতে অ্যাক্সেসের জন্য দরকারী যা কোনও শ্রেণিতে ওভাররাইড করা হয়েছে। সার্চ অর্ডারটি গেটআটার () দ্বারা ব্যবহৃত ঠিক একই ধরণের নিজেই এড়ানো যায়।
এবং পাইথন 3.x এ আপনি কেবল super()
কোনও প্যারামিটার ছাড়াই ক্লাসের অভ্যন্তরে ব্যবহার করতে পারেন ।
type(x)
। যদি আমি কোনও বিল্ট ইন টাইপ সাবক্লাসিং না করে থাকি তবে নতুন স্টাইলের ক্লাসগুলির মধ্যে আমি দেখতে পাচ্ছি এমন কোনও সুবিধা হবে বলে মনে হয় না। এর অসুবিধাও রয়েছে, যা অতিরিক্ত টাইপ করা(object)
।