উত্তর:
অ্যালেক্স ভাল সংক্ষিপ্তসার কিন্তু আশ্চর্যজনকভাবে, খুব সংক্ষিপ্ত।
প্রথমে, আমি অ্যালেক্সের পোস্টের মূল বিষয়গুলি পুনরায় বলি :
__repr__
লক্ষ্য দ্ব্যর্থহীন হতে হয়__str__
লক্ষ্য হ'ল পাঠযোগ্য__str__
ব্যবহারগুলিতে থাকা অবজেক্টগুলি '__repr__
ডিফল্ট বাস্তবায়ন অকেজো
এটি বেশিরভাগ ক্ষেত্রেই আশ্চর্যজনক কারণ পাইথনের ডিফল্টগুলি মোটামুটি কার্যকর হতে থাকে। যাইহোক, এই ক্ষেত্রে, একটি ডিফল্ট থাকার জন্য __repr__
এটি কাজ করবে:
return "%s(%r)" % (self.__class__, self.__dict__)
খুব বিপজ্জনক হত (উদাহরণস্বরূপ, বস্তু একে অপরের রেফারেন্স দিলে অসীম পুনরাবৃত্তিতে প্রবেশ করা খুব সহজ)। তাই পাইথন পুলিশ আউট। মনে রাখবেন যে একটি ডিফল্ট রয়েছে যা সত্য: যদি __repr__
সংজ্ঞায়িত হয় এবং __str__
না হয় তবে অবজেক্টটি যেমন আচরণ করবে__str__=__repr__
।
এর অর্থ, সরল ভাষায়: আপনি প্রয়োগ করেন এমন প্রতিটি বস্তুর একটি কার্যকরী হওয়া উচিত __repr__
যা অবজেক্টটি বোঝার জন্য ব্যবহারযোগ্য। বাস্তবায়ন al __str__
চ্ছিক: আপনার যদি একটি "সুন্দর মুদ্রণ" কার্যকারিতা প্রয়োজন হয় (উদাহরণস্বরূপ, রিপোর্ট জেনারেটর দ্বারা ব্যবহৃত)।
লক্ষ্যটি __repr__
দ্ব্যর্থহীন হওয়া
আমাকে ঠিক বাইরে এসে বলতে দিন - আমি ডিবাগারগুলিতে বিশ্বাস করি না। কোনও ডিবাগার কীভাবে ব্যবহার করতে হয় তা আমি সত্যিই জানি না এবং কখনই এটি গুরুত্ব সহকারে ব্যবহার করি নি। তদ্ব্যতীত, আমি বিশ্বাস করি যে ডিবাগারগুলিতে বড় দোষ তাদের মূল প্রকৃতি deb বেশিরভাগ ব্যর্থতা যেগুলি আমি ডিবাগ করি সেগুলি বহুদিন আগে হয়েছিল, অনেক দূরে একটি ছায়াপথের মধ্যে। এর অর্থ হ'ল লগিংয়ে আমি ধর্মীয় উত্সাহ সহ বিশ্বাস করি। লগিং হ'ল যে কোনও শালীন আগুন এবং ভুলে যাওয়া সার্ভার সিস্টেমের লাইফব্লুড। পাইথন লগ করা সহজ করে তোলে: সম্ভবত কিছু প্রকল্প নির্দিষ্ট র্যাপারগুলির সাথে আপনার কেবলমাত্র একটি দরকার
log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)
তবে আপনাকে শেষ পদক্ষেপটি করতে হবে - নিশ্চিত করুন যে আপনি প্রয়োগ করেন এমন প্রতিটি বস্তুর একটি কার্যকর পুনরাবৃত্তি রয়েছে, সুতরাং এর মতো কোডটি কেবল কাজ করতে পারে। এই কারণেই "alভাল" জিনিসটি সামনে আসে: আপনার যদি পর্যাপ্ত তথ্য থাকে তবে এর eval(repr(c))==c
অর্থ আপনি যা জানার তা সবই জানেন c
। যদি এটি যথেষ্ট সহজ হয় তবে কমপক্ষে অস্পষ্টভাবে, এটি করুন। যদি তা না হয় তবে নিশ্চিত হয়ে নিন যে c
কোনওভাবেই আপনার কাছে পর্যাপ্ত তথ্য রয়েছে । আমি সাধারণত একটি Eval মত বিন্যাস ব্যবহার করুন: "MyClass(this=%r,that=%r)" % (self.this,self.that)
। এর অর্থ এই নয় যে আপনি প্রকৃতপক্ষে মাইক্লাস নির্মাণ করতে পারেন, বা এগুলি সঠিক নির্মাণকারীর যুক্তি রয়েছে - তবে "এই উদাহরণটি সম্পর্কে আপনার যা জানার দরকার এটি এটি এটিই" প্রকাশ করার জন্য এটি একটি দরকারী ফর্ম।
দ্রষ্টব্য: আমি %r
উপরে ব্যবহার করেছি , না %s
। আপনি সর্বদা বাস্তবায়নের অভ্যন্তরে repr()
[বা %r
বিন্যাসকরণের চরিত্রটি সমানভাবে] ব্যবহার করতে চান __repr__
, বা আপনি repr এর লক্ষ্যকে পরাস্ত করছেন। আপনি আলাদা করতে সক্ষম হতে চান MyClass(3)
এবং MyClass("3")
।
এর লক্ষ্য __str__
হ'ল পাঠযোগ্য
বিশেষত, এটি দ্ব্যর্থহীন হওয়ার উদ্দেশ্যে নয় - লক্ষ্য করুন str(3)==str("3")
। তেমনিভাবে, আপনি যদি কোনও আইপি বিমূর্তি প্রয়োগ করেন তবে এর স্ট্রিংটি 192.168.1.1 এর মতো দেখতে ঠিক আছে। কোনও তারিখ / সময় বিমূর্তি প্রয়োগ করার সময়, স্ট্রিং "2010/4/12 15:35:22", ইত্যাদি হতে পারে ইত্যাদি The লক্ষ্যটি এমনভাবে উপস্থাপন করা হয় যে কোনও প্রোগ্রামার নয়, একজন ব্যবহারকারী এটি পড়তে চায়। অকেজো অঙ্কগুলি কেটে ফেলুন, অন্য কোনও শ্রেণির হওয়ার ভান করুন - যতক্ষণ এটি পঠনযোগ্যতা সমর্থন করে, এটি একটি উন্নতি।
ধারকগুলির __str__
ব্যবহারগুলিতে থাকা অবজেক্টগুলি '__repr__
এটা অবাক লাগে, তাই না? এটি সামান্য, তবে এটি যদি তাদের ব্যবহার করে তবে তা কতটা পাঠযোগ্য হবে __str__
?
[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]
বেশি না. বিশেষত, একটি ধারকটির স্ট্রিংগুলি এর স্ট্রিং প্রতিনিধিত্বকে বিরক্ত করতে খুব সহজ উপায় খুঁজে পাবে। অস্পষ্টতার মুখে, মনে রাখবেন, পাইথন অনুমান করার প্রলোভনটিকে প্রতিহত করেছেন। আপনি কোনও তালিকা মুদ্রণ করার সময় যদি উপরের আচরণটি চান তবে ঠিক
print "[" + ", ".join(l) + "]"
(আপনি সম্ভবত অভিধানগুলি সম্পর্কে কী করতে হবে তাও বুঝতে পারেন।
সারসংক্ষেপ
বাস্তবায়ন __repr__
কোনো শ্রেণী আপনি বাস্তবায়ন জন্য। এটি দ্বিতীয় প্রকৃতি হওয়া উচিত। বাস্তবায়ন __str__
যদি আপনি মনে করেন এটি একটি স্ট্রিং সংস্করণ পাঠযোগ্যতা পাশ ভুল আছে দরকারী হবে।
__repr__
ডিবাগিংয়ের জন্য আমার যা প্রয়োজন ছিল তা দেখা যাচ্ছে । আপনার সাহায্যের জন্য ধন্যবাদ।
আমার থাম্বের নিয়ম: __repr__
বিকাশকারীদের __str__
জন্য, গ্রাহকদের জন্য।
__str__
এত সাধারণ বিকাশকারীদের পঠনযোগ্য অবজেক্ট ব্যবহার করবে । অন্যদিকে, __repr__
এসডিকে বিকাশকারীরা নিজেরাই।
আপনি অন্যথায় তা নিশ্চিত করার জন্য বিশেষভাবে কাজ না করা সর্বাধিক শ্রেণীর কোনওটির জন্য সহায়ক ফলাফল হয় না:
>>> class Sic(object): pass
...
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>>
আপনি যেমন দেখেন - কোনও পার্থক্য নেই এবং শ্রেণি এবং অবজেক্টের বাইরে কোনও তথ্য নেই id
। আপনি যদি কেবল দুটিটির একটিতে ওভাররাইড করেন ...:
>>> class Sic(object):
... def __repr__(object): return 'foo'
...
>>> print str(Sic())
foo
>>> print repr(Sic())
foo
>>> class Sic(object):
... def __str__(object): return 'foo'
...
>>> print str(Sic())
foo
>>> print repr(Sic())
<__main__.Sic object at 0x2617f0>
>>>
যেমন আপনি দেখতে পাচ্ছেন, যদি আপনি ওভাররাইড __repr__
করেন __str__
, তবে এটি বিপরীত নয় for
অন্যান্য গুরুত্বপূর্ণ টিডবিটগুলি জানার জন্য: __str__
বিল্ট-অন পাত্রে এটি থাকা আইটেমগুলির জন্য __repr__
, না __str__
, ব্যবহার করে। এবং সাধারণ ডক্সগুলিতে এই বিষয়টির শব্দ পাওয়া সত্ত্বেও, কেউই __repr__
অবজেক্টগুলির স্ট্রিং তৈরি করে বিরক্ত করে নাeval
একটি সমান বস্তু তৈরি করতে ব্যবহার করতে পারে (এটি কেবল খুব শক্ত, এবং কীভাবে প্রাসঙ্গিক মডিউলটি আসলে আমদানি করা হয়েছিল তা না জেনে এটি আসলে তৈরি করে অসম্ভব সমতল)।
সুতরাং, আমার পরামর্শ: __str__
যুক্তিসঙ্গতভাবে মানব-পঠনযোগ্য তৈরি করার দিকে মনোনিবেশ করুন এবং __repr__
আপনি যতটা সম্ভব দ্ব্যর্থহীন, এমনকি যদি এটির __repr__
প্রত্যাবর্তিত মানটিকে ইনপুট হিসাবে গ্রহণযোগ্য করে তোলার অস্পষ্ট লক্ষ্যমাত্রায় হস্তক্ষেপ করে __eval__
!
eval(repr(foo))
সমান বস্তুর মূল্যায়ন করে foo
। আপনি ঠিক বলেছেন যে এটি আমার পরীক্ষার কেসগুলির বাইরে কাজ করবে না যেহেতু আমি জানি না যে মডিউলটি কীভাবে আমদানি করা হয়, তবে এটি অন্তত নিশ্চিত করে যে এটি কোনও অনুমানযোগ্য প্রসঙ্গে কাজ করে। আমি মনে করি ফলাফলের __repr__
পরিমাণটি যথেষ্ট পরিমাণে সুস্পষ্ট হলে এটি মূল্যায়নের একটি ভাল উপায় । ইউনিট পরীক্ষায় __repr__
এটি করা ক্লাসে পরিবর্তনগুলি অনুসরণ করে তা নিশ্চিত করতে সহায়তা করে ।
eval(repr(spam)) == spam
(কমপক্ষে সঠিক প্রসঙ্গে), বা eval(repr(spam))
একটি উত্থাপন করে SyntaxError
। এইভাবে আপনি বিভ্রান্তি এড়ান। (এবং এটি বিল্টিন এবং বেশিরভাগ স্টডিলিবের জন্য প্রায় সত্য, উদাহরণস্বরূপ, পুনরাবৃত্ত তালিকাগুলি, যেখানে a=[]; a.append(a); print(eval(repr(a)))
আপনাকে দেয় [[Ellipses]]
…) অবশ্যই ইউনিট পরীক্ষায় স্যানিটি পরীক্ষা না করে আমি আসলে এটি ব্যবহার করতে পারি না eval(repr(spam))
... তবে আমি না কখনও কখনও কপি এবং পেস্ট করুন repr(spam)
একটি ইন্টারেক্টিভ অধিবেশন মধ্যে।
__str__
প্রতিটি উপাদানের পরিবর্তে ব্যবহার হবে না __repr__
? আমার কাছে এটিকে সাধারণভাবে ভুল বলে মনে হচ্ছে, যেহেতু আমি __str__
আমার অবজেক্টে একটি পঠনযোগ্য প্রয়োগ করেছি এবং যখন এটি কোনও তালিকার অংশ তখন আমি __repr__
পরিবর্তে কুশলীকে দেখতে পাচ্ছি ।
eval(repr(x))
বিল্টিন টাইপের ক্ষেত্রেও ব্যর্থ হয়: সিনট্যাক্স এরিয়ারটি class A(str, Enum): X = 'x'
বাড়িয়ে তুলবে eval(repr(A.X))
। এটি দুঃখজনক, তবে বোধগম্য। বিটিডাব্লু, eval(str(A.X))
আসলে কাজ করে তবে অবশ্যই class A
সুযোগটি যদি থাকে - তাই সম্ভবত এটি খুব কার্যকর নয়।
str
ব্যবহারের উপাদান repr
কারণ [1, 2, 3]
! = ["1", "2, 3"]
।
__repr__
: পাইথন অবজেক্টের উপস্থাপনা সাধারণত এভাল এটিকে আবার সেই বস্তুতে রূপান্তরিত করে
__str__
: আপনি যা ভাবেন তা হ'ল পাঠ্য আকারে object
যেমন
>>> s="""w'o"w"""
>>> repr(s)
'\'w\\\'o"w\''
>>> str(s)
'w\'o"w'
>>> eval(str(s))==s
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1
w'o"w
^
SyntaxError: EOL while scanning single-quoted string
>>> eval(repr(s))==s
True
সংক্ষেপে, এর লক্ষ্যটি
__repr__
দ্ব্যর্থহীন হওয়া এবং__str__
পঠনযোগ্য।
এখানে একটি ভাল উদাহরণ:
>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2012-03-14 09:21:58.130922'
>>> repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'
Repr জন্য এই ডকুমেন্টেশন পড়ুন:
repr(object)
কোনও বস্তুর মুদ্রণযোগ্য উপস্থাপনাযুক্ত একটি স্ট্রিং ফিরিয়ে দিন। এটি রূপান্তর দ্বারা উত্পন্ন একই মান (বিপরীত উদ্ধৃতি)। সাধারণ ক্রিয়াকলাপ হিসাবে এই ক্রিয়াকলাপটি অ্যাক্সেস করতে সক্ষম হওয়া কখনও কখনও দরকারী। অনেক ধরণের ক্ষেত্রে, এই ফাংশনটি এমন একটি স্ট্রিং ফেরত দেওয়ার চেষ্টা করে যা পাস করার সময় একই মান সহ একটি বস্তু উত্পন্ন করবে
eval()
, অন্যথায় উপস্থাপনাটি একটি কোণে বন্ধনীতে আবদ্ধ একটি স্ট্রিং যাতে এতে অতিরিক্ত তথ্যের সাথে অবজেক্টের ধরণের নাম যুক্ত থাকে is প্রায়শই বস্তুর নাম এবং ঠিকানা সহ including কোনও শ্রেণিটি কোনও__repr__()
পদ্ধতি নির্ধারণ করে এই ফাংশনটি কীভাবে তার দৃষ্টান্তগুলির জন্য ফিরে আসে তা নিয়ন্ত্রণ করতে পারে ।
এখানে স্ট্রিংয়ের জন্য ডকুমেন্টেশন রয়েছে:
str(object='')
কোনও স্ট্রিংটি প্রত্যাবর্তন করুন যাতে কোনও বস্তুর দুর্দান্ত মুদ্রণযোগ্য উপস্থাপনা থাকে। স্ট্রিংগুলির জন্য, এটি স্ট্রিংটি নিজেই দেয়। এর সাথে পার্থক্যটি
repr(object)
হ'লstr(object)
সর্বদা গ্রহণযোগ্য স্ট্রিংটি ফেরত দেওয়ার চেষ্টা করে নাeval()
; এর লক্ষ্য হ'ল একটি মুদ্রণযোগ্য স্ট্রিং ফিরিয়ে দেওয়া। যদি কোনও যুক্তি না দেওয়া হয়, খালি স্ট্রিংটি প্রদান করে''
,।
পাইথনের মধ্যে
__str__
এবং পার্থক্য কী__repr__
?
__str__
("ডান্ডার (ডাবল-আন্ডারস্কোর) স্ট্রিং" হিসাবে পড়ুন)) এবং __repr__
হিসাবে পড়ুন ("ডান্ডার-রিপার" হিসাবে পড়ুন ("উপস্থাপনার জন্য")) উভয়ই বিশেষ পদ্ধতি যা বস্তুর অবস্থার উপর ভিত্তি করে স্ট্রিংগুলি ফেরত দেয়।
__repr__
__str__
অনুপস্থিত থাকলে ব্যাকআপ আচরণ সরবরাহ করে ।
সুতরাং প্রথমে এমন একটি লিখতে হবে __repr__
যা আপনাকে যে স্ট্রিংটি দেয় তার থেকে সমতুল্য বস্তুটিকে পুনরায় স্থাপন করতে দেয় যেমন উদাহরণস্বরূপ ব্যবহার করে eval
বা পাইথন শেলের জন্য অক্ষরের জন্য অক্ষর টাইপ করে।
পরে যে কোনও সময়, কেউ __str__
যখন প্রয়োজন মনে করেন তখন এটি ব্যবহারকারী-পাঠযোগ্য স্ট্রিং উপস্থাপনের জন্য লিখতে পারেন ।
__str__
আপনি একটি বস্তু প্রিন্ট, অথবা এটি পাস থাকলে format
, str.format
অথবা str
, তারপর একটি __str__
পদ্ধতি সংজ্ঞায়িত করা হয়, যে পদ্ধতি বলা হবে, অন্যথায়, __repr__
ব্যবহার করা হবে।
__repr__
__repr__
পদ্ধতি builtin ফাংশন দ্বারা বলা হয় repr
এবং আপনার কি পাইথন শেল উপর প্রতিধ্বনিত যখন এটা একটি অভিব্যক্তি যে একটি বস্তু ফেরৎ মূল্যায়ণ করা হয়।
যেহেতু এটির জন্য একটি ব্যাকআপ সরবরাহ করে __str__
, আপনি যদি কেবল একটি লিখতে পারেন তবে শুরু করুন__repr__
এখানে অন্তর্নির্মিত সহায়তা এখানে repr
:
repr(...)
repr(object) -> string
Return the canonical string representation of the object.
For most object types, eval(repr(object)) == object.
এটি হ'ল, বেশিরভাগ অবজেক্টের জন্য, আপনি যদি প্রিন্ট করে যা টাইপ করেন repr
, আপনার সমতুল্য কোনও বস্তু তৈরি করতে সক্ষম হওয়া উচিত। তবে এটি ডিফল্ট বাস্তবায়ন নয়।
__repr__
ডিফল্ট অবজেক্টটি __repr__
হ'ল ( সি পাইথন উত্স ) এর মতো:
def __repr__(self):
return '<{0}.{1} object at {2}>'.format(
self.__module__, type(self).__name__, hex(id(self)))
এর অর্থ ডিফল্টরূপে আপনি বস্তুটি যে মডিউলটি, ক্লাসের নাম এবং মেমরিতে তার অবস্থানের হেক্সাডেসিমাল উপস্থাপনাটি মুদ্রণ করবেন - উদাহরণস্বরূপ:
<__main__.Foo object at 0x7f80665abdd0>
এই তথ্যটি খুব কার্যকর নয়, তবে কেউ কীভাবে কোনও নির্দিষ্ট উদাহরণের প্রামাণিক উপস্থাপনাটি সঠিকভাবে তৈরি করতে পারে তা আবিষ্কার করার কোনও উপায় নেই এবং এটি কোনও কিছুর চেয়ে ভাল, কমপক্ষে কীভাবে আমরা স্মরণে এটি অনন্যভাবে সনাক্ত করতে পারি তা আমাদের জানান।
__repr__
দরকারী হতে পারে?পাইথন শেল এবং datetime
অবজেক্ট ব্যবহার করে এটি কতটা কার্যকর হতে পারে তা দেখুন । প্রথমে আমাদের datetime
মডিউলটি আমদানি করতে হবে :
import datetime
যদি আমরা datetime.now
শেলটিতে কল করি তবে আমরা সমতুল্য তারিখের অবজেক্টটি পুনরায় তৈরি করার জন্য প্রয়োজনীয় সমস্ত কিছু দেখতে পাব। এটি তারিখের সময় দ্বারা তৈরি করা হয় __repr__
:
>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
আমরা যদি ডেটটাইম অবজেক্টটি প্রিন্ট করি তবে আমরা একটি সুন্দর মানব পাঠযোগ্য (আসলে, আইএসও) ফর্ম্যাটটি দেখতে পাচ্ছি। এটি ডেটটাইমের দ্বারা প্রয়োগ করা হয় __str__
:
>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951
আমরা যে অবজেক্টটি হারিয়েছি তা পুনরায় তৈরি করা সহজ বিষয় কারণ আমরা __repr__
আউটপুট থেকে অনুলিপি করে আটকানো এবং তারপরে এটি মুদ্রণ করে একটি ভেরিয়েবলের কাছে অর্পণ করি নি এবং আমরা এটি অন্য বস্তুর মতো একই মানব পাঠযোগ্য আউটপুটে পেয়েছি:
>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180
আপনি যখন বিকাশ করছেন, আপনি যদি সম্ভব হয় তবে একই অবস্থায় অবজেক্টগুলি পুনরুত্পাদন করতে সক্ষম হতে চাইবেন। এটি উদাহরণস্বরূপ, ডেটটাইম অবজেক্টটি কীভাবে সংজ্ঞা দেয় __repr__
( পাইথন উত্স )। এটি মোটামুটি জটিল, কারণ এই জাতীয় কোনও বস্তুর পুনরুত্পাদন করার জন্য প্রয়োজনীয় সমস্ত গুণাবলী:
def __repr__(self):
"""Convert to formal string, for repr()."""
L = [self._year, self._month, self._day, # These are never zero
self._hour, self._minute, self._second, self._microsecond]
if L[-1] == 0:
del L[-1]
if L[-1] == 0:
del L[-1]
s = "%s.%s(%s)" % (self.__class__.__module__,
self.__class__.__qualname__,
", ".join(map(str, L)))
if self._tzinfo is not None:
assert s[-1:] == ")"
s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
if self._fold:
assert s[-1:] == ")"
s = s[:-1] + ", fold=1)"
return s
যদি আপনি চান যে আপনার অবজেক্টের আরও বেশি মানব পাঠযোগ্য উপস্থাপনা রয়েছে তবে আপনি __str__
পরবর্তীটি প্রয়োগ করতে পারেন । ডেটটাইম অবজেক্ট ( পাইথন উত্স ) কীভাবে প্রয়োগ __str__
করে তা এখানে সহজেই কার্যকর হয় কারণ এটি ইতিমধ্যে আইএসও ফর্ম্যাটে প্রদর্শিত করার ফাংশন রয়েছে:
def __str__(self):
"Convert to string, for str()."
return self.isoformat(sep=' ')
__repr__ = __str__
?এটি সেটিংসের প্রস্তাব দেয় এমন আরও একটি উত্তরের সমালোচনা __repr__ = __str__
।
সেটিংটি __repr__ = __str__
নিরীহ - __repr__
এটি একটি ফ্যালব্যাক __str__
এবং এটি __repr__
, ডিবাগিংয়ের ক্ষেত্রে বিকাশকারীদের ব্যবহারের জন্য রচিত, আপনি একটি লেখার আগে লেখা উচিত __str__
।
আপনার __str__
কেবল তখনই প্রয়োজন যখন আপনার কোনও বস্তুর পাঠ্য উপস্থাপনা প্রয়োজন।
__repr__
আপনি যে জিনিসগুলি লিখেছেন তার জন্য সংজ্ঞা দিন যাতে আপনার বিকাশকালে এটি ব্যবহার করার সময় আপনার এবং অন্যান্য বিকাশকারীদের একটি পুনরায় উত্পাদনযোগ্য উদাহরণ থাকে have __str__
আপনি যখন এর কোনও মানব পাঠযোগ্য স্ট্রিং প্রতিনিধিত্বের প্রয়োজন তখন সংজ্ঞা দিন।
type(obj).__qualname__
?
হ্যান্স পেটার ল্যাংট্যাঞ্জেনের গণ্য বিজ্ঞানের জন্য পাইথন স্ক্রিপ্টিং বইয়ের 358 পৃষ্ঠায় এটি পরিষ্কারভাবে জানিয়েছে যে
__repr__
বস্তুর সম্পূর্ণ স্ট্রিং উপস্থাপনা করে লক্ষ্য;__str__
মুদ্রণের জন্য একটা চমৎকার স্ট্রিং আসতে হয়।সুতরাং, আমি তাদের হিসাবে বুঝতে পছন্দ করি
ব্যবহারকারীর দৃষ্টিকোণ থেকে যদিও পাইথন শেখার সময় এটি আমি একটি ভুল বোঝাবুঝি করেছি।
একটি ছোট তবে ভাল উদাহরণ নীচে একই পৃষ্ঠায় দেওয়া হয়েছে:
In [38]: str('s')
Out[38]: 's'
In [39]: repr('s')
Out[39]: "'s'"
In [40]: eval(str('s'))
Traceback (most recent call last):
File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
eval(str('s'))
File "<string>", line 1, in <module>
NameError: name 's' is not defined
In [41]: eval(repr('s'))
Out[41]: 's'
repr
পুনরুত্পাদন হিসাবে উল্লেখ করা এক ধরণের বিভ্রান্তিকর । প্রতিনিধিত্বমূলক হিসাবে এটি ভাবা ভাল।
প্রদত্ত সমস্ত উত্তর ছাড়াও আমি কয়েকটি পয়েন্ট যুক্ত করতে চাই: -
1) __repr__()
যখন আপনি কেবল ইন্টারেক্টিভ পাইথন কনসোলে অবজেক্টের নাম লিখুন এবং এন্টার টিপুন তখনই অনুরোধ করা হয়।
2) __str__()
যখন আপনি মুদ্রণ বিবৃতি সহ অবজেক্টটি ব্যবহার করেন তখন আপনাকে অনুরোধ করা হয়।
3) যদি, __str__
অনুপস্থিত হয়, তাহলে মুদ্রণ এবং str()
চালান ব্যবহার করে যে কোনও ফাংশন__repr__()
অবজেক্টের ।
4) __str__()
পাত্রে, যখন অনুরোধ করা হয় তখন এতে __repr__()
থাকা উপাদানগুলির পদ্ধতি কার্যকর করে।
5) এর str()
মধ্যে বলা হয় __str__()
কোনও বেস কেস ছাড়াই সম্ভাব্য পুনরাবৃত্তি হতে পারে এবং সর্বাধিক পুনরাবৃত্তির গভীরতায় ত্রুটি।
6) __repr__()
কল করতে পারে repr()
যা ইতিমধ্যে উপস্থাপিত বস্তুর সাথে প্রতিস্থাপন করে স্বয়ংক্রিয়ভাবে অসীম পুনরাবৃত্তি এড়ানোর চেষ্টা করবে ...
।
সমস্ত সততা, eval(repr(obj))
কখনও ব্যবহার করা হয় না। যদি আপনি নিজেকে এটি ব্যবহার করে দেখতে পান তবে আপনার থামানো উচিত, কারণ eval
এটি বিপজ্জনক, এবং স্ট্রিংগুলি আপনার অবজেক্টগুলিকে সিরিয়ালাইজ করার একটি খুব অযোগ্য উপায় (ব্যবহার করুনpickle
পরিবর্তে করুন)।
অতএব, আমি সেট করার পরামর্শ দেব __repr__ = __str__
। কারণটি হ'ল উপাদানগুলিতে str(list)
কল repr
করা (আমি এটিকে পাইথনের সবচেয়ে বড় নকশার ত্রুটি হিসাবে বিবেচনা করি যা পাইথন 3 দ্বারা সম্বোধন করা হয়নি)। একটি প্রকৃতপক্ষে repr
সম্ভবত আউটপুট হিসাবে খুব সহায়ক হবে না print [your, objects]
।
এটির যোগ্যতা অর্জন করার জন্য, আমার অভিজ্ঞতায়, repr
ফাংশনের সর্বাধিক দরকারী ব্যবহারের ক্ষেত্রে হ'ল একটি স্ট্রিংকে অন্য স্ট্রিংয়ের (স্ট্রিং ফর্ম্যাটিং ব্যবহার করে) ভিতরে রাখা। এইভাবে, আপনার উদ্ধৃতি বা কোনও কিছু নিয়ে ভাবতে হবে না। তবে মনে রাখবেন eval
এখানে কোনও ঘটনা ঘটছে না।
eval(repr(obj))
হ'ল স্যানিটি টেস্ট এবং একটি নিয়মের নিয়ম - যদি এটি আসল অবজেক্টটি সঠিকভাবে পুনরায় তৈরি করে তবে আপনার একটি __repr__
কার্যকর প্রয়োগ রয়েছে। আপনি আসলে এইভাবে অবজেক্টগুলিকে সিরিয়ালাইজ করবেন না এমন উদ্দেশ্য নয়।
eval
অন্তর্নিহিত বিপজ্জনক নয়। চেয়ে বেশি বিপজ্জনক নয় unlink
, open
অথবা ফাইল লেখা। আমাদের কি ফাইলগুলিতে লেখা বন্ধ করা উচিত কারণ সম্ভবত কোনও দূষিত আক্রমণটি সামগ্রীকে ভিতরে রাখার জন্য একটি স্বেচ্ছাসেবী ফাইলের পথ ব্যবহার করতে পারে? বোবা লোকেরা বোকার মতো ব্যবহার করলে সবকিছু বিপজ্জনক। ইডিয়োসি বিপজ্জনক। ডানিং-ক্রুগার প্রভাব বিপজ্জনক। eval
শুধু একটি ফাংশন।
এটি সহজভাবে বলতে:
__str__
অন্যের দ্বারা সহজেই পড়ার জন্য আপনার অবজেক্টের স্ট্রিং প্রতিনিধিত্ব দেখাতে ব্যবহৃত হয় ।
__repr__
একটি স্ট্রিং উপস্থাপনা দেখানোর জন্য ব্যবহৃত হয় অবজেক্ট।
বলি আমি একটি তৈরি করতে চাই Fraction
শ্রেণি যেখানে ভগ্নাংশের স্ট্রিং প্রতিনিধিত্ব '(1/2)' এবং অবজেক্ট (ভগ্নাংশ বর্গ )কে 'ভগ্নাংশ (1,2)' হিসাবে উপস্থাপন করা হবে
সুতরাং আমরা একটি সাধারণ ভগ্নাংশ শ্রেণি তৈরি করতে পারি:
class Fraction:
def __init__(self, num, den):
self.__num = num
self.__den = den
def __str__(self):
return '(' + str(self.__num) + '/' + str(self.__den) + ')'
def __repr__(self):
return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'
f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)
থেকে একটি (একটি বেসরকারী) পাইথন রেফারেন্স উইকি (আর্কাইভ অনুলিপি) effbot দ্বারা:
__str__
" কোনও অবজেক্টের" অনানুষ্ঠানিক "স্ট্রিং প্রতিনিধিত্ব গণনা করে This __repr__
এটির থেকে পৃথক হয় এটি বৈধ পাইথন এক্সপ্রেশন হতে হবে না: পরিবর্তে আরও সুবিধাজনক বা সংক্ষিপ্ত উপস্থাপনা ব্যবহার করা যেতে পারে। "
__repr__
ভিল্ড পাইথন এক্সপ্রেশনটি কোনও উপায়ে ফেরানোর দরকার নেই।
একটি দিক যা অন্য উত্তরে অনুপস্থিত। এটি সত্য যে সাধারণভাবে প্যাটার্নটি হ'ল:
__str__
: মানব-পঠনযোগ্য__repr__
: দ্ব্যর্থহীন, সম্ভবত মেশিন দ্বারা পঠনযোগ্য viaeval
দুর্ভাগ্যক্রমে, এই পার্থক্যটি ত্রুটিযুক্ত, কারণ পাইথন আরপিএল এবং __repr__
আইপিথনও একটি আরপিএল কনসোলে আইকন প্রিন্ট করার জন্য ব্যবহার করে ( পাইথন এবং আইপিথনের সম্পর্কিত প্রশ্নগুলি দেখুন )। সুতরাং, যে প্রকল্পগুলি ইন্টারেক্টিভ কনসোল কাজের জন্য লক্ষ্যযুক্ত (যেমন, নম্পি বা পান্ডস) উপরের নিয়মগুলিকে উপেক্ষা করে __repr__
পরিবর্তে একটি মানব-পঠনযোগ্য বাস্তবায়ন সরবরাহ করতে শুরু করেছে।
সাবলীল পাইথন বইটি থেকে :
পাইথন অবজেক্টের প্রাথমিক প্রয়োজন হ'ল নিজের ব্যবহারযোগ্য স্ট্রিং উপস্থাপনা সরবরাহ করা, একটি ডিবাগিং এবং লগিংয়ের জন্য ব্যবহৃত হয়, অন্য ব্যবহারকারীদের উপস্থাপনের জন্য শেষ ব্যবহারকারীদের। এজন্য ডেটা মডেলটিতে
বিশেষ পদ্ধতি__repr__
এবং__str__
উপস্থিতি রয়েছে।
দুর্দান্ত উত্তরগুলি ইতিমধ্যে __str__
এবং এর মধ্যে পার্থক্যটি কভার করে __repr__
, যা আমার জন্য প্রাক্তনকে এমনকি শেষ ব্যবহারকারী দ্বারা পঠনযোগ্য এবং পরবর্তীকর্মীরা বিকাশকারীদের পক্ষে যতটা সম্ভব কার্যকর হিসাবে ফোটায়। এটি দিয়ে, আমি দেখতে পেয়েছি যে __repr__
প্রায়শই ডিফল্ট প্রয়োগটি এই লক্ষ্য অর্জনে ব্যর্থ হয় কারণ এটি বাদ পড়ে বিকাশকারীদের জন্য দরকারী তথ্য ।
এই কারণে, যদি আমার যথেষ্ট সহজ থাকে তবে আমি __str__
সাধারণত উভয় বিশ্বের সেরা কিছু অর্জন করার চেষ্টা করি:
def __repr__(self):
return '{0} ({1})'.format(object.__repr__(self), str(self))
একটি গুরুত্বপূর্ণ বিষয় মনে রাখবেন যে ধারকগুলির
__str__
ব্যবহারগুলিতে থাকা অবজেক্টগুলি '__repr__
।
>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"
পাইথন পাঠযোগ্যতা উপর unambiguity উপযোগী , __str__
একটি কল tuple
কল অন্তর্ভুক্ত বস্তু ' __repr__
, "আনুষ্ঠানিক" একটি বস্তুর উপস্থাপনা। যদিও আনুষ্ঠানিক উপস্থাপনাটি কোনও অনানুষ্ঠানিক পাঠের চেয়ে পড়া শক্ত, তবে এটি বাগের তুলনায় দ্ব্যর্থহীন এবং আরও দৃ more়।
__repr__
এটি ( __str__
) সংজ্ঞায়িত না হলে এটি ব্যবহার করে ! সুতরাং, আপনি ভুল।
সংক্ষেপে:
class Demo:
def __repr__(self):
return 'repr'
def __str__(self):
return 'str'
demo = Demo()
print(demo) # use __str__, output 'str' to stdout
s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'
import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout
from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')
যখন print()
এর ফলাফলে বলা decimal.Decimal(23) / decimal.Decimal("1.05")
কাঁচা সংখ্যা ছাপা হয়; এই আউটপুটটি স্ট্রিং ফর্মে রয়েছে যা দিয়ে অর্জন করা যায় __str__()
। যদি আমরা সহজেই এক্সপ্রেশনটি প্রবেশ করি তবে আমরা একটি decimal.Decimal
আউটপুট পাই - এই আউটপুটটি প্রতিনিধিত্বমূলক আকারে যা অর্জন করা যায় __repr__()
। সমস্ত পাইথন অবজেক্টের দুটি আউটপুট ফর্ম রয়েছে। স্ট্রিং ফর্মটি মানব-পঠনযোগ্য হওয়ার জন্য ডিজাইন করা হয়েছে। উপস্থাপনা ফর্মটি আউটপুট উত্পাদন করার জন্য ডিজাইন করা হয়েছে যে পাইথন ইন্টারপ্রেটারকে খাওয়ানো হলে (যখন সম্ভব) উপস্থাপিত বস্তুকে পুনরুত্পাদন করবে।
__str__
কল করে কোনও বস্তুতে আহ্বান করা যেতে পারে str(obj)
এবং একটি মানব পাঠযোগ্য স্ট্রিংটি ফিরিয়ে আনা উচিত।
__repr__
কল করে কোনও বস্তুতে আহ্বান করা যেতে পারে repr(obj)
এবং অভ্যন্তরীণ অবজেক্ট (অবজেক্ট ক্ষেত্র / বৈশিষ্ট্য) ফেরত দেওয়া উচিত
এই উদাহরণ সাহায্য করতে পারে:
class C1:pass
class C2:
def __str__(self):
return str(f"{self.__class__.__name__} class str ")
class C3:
def __repr__(self):
return str(f"{self.__class__.__name__} class repr")
class C4:
def __str__(self):
return str(f"{self.__class__.__name__} class str ")
def __repr__(self):
return str(f"{self.__class__.__name__} class repr")
ci1 = C1()
ci2 = C2()
ci3 = C3()
ci4 = C4()
print(ci1) #<__main__.C1 object at 0x0000024C44A80C18>
print(str(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(repr(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(ci2) #C2 class str
print(str(ci2)) #C2 class str
print(repr(ci2)) #<__main__.C2 object at 0x0000024C44AE12E8>
print(ci3) #C3 class repr
print(str(ci3)) #C3 class repr
print(repr(ci3)) #C3 class repr
print(ci4) #C4 class str
print(str(ci4)) #C4 class str
print(repr(ci4)) #C4 class repr
বুঝতে __str__
এবং __repr__
স্বজ্ঞাত এবং স্থায়ীভাবে এগুলিকে একেবারে আলাদা করুন।
__str__
চোখের পাঠযোগ্যতার জন্য কোনও প্রদত্ত বস্তুর স্ট্রিং ছদ্মবেশযুক্ত শরীরটি ফিরিয়ে দিন
__repr__
ফিরিয়ে আনুন চিহ্নিত করার জন্য নির্ধারিত অবজেক্টের আসল দেহকে (নিজেই ফিরে আসুন) ফিরিয়ে দিন।
এটি একটি উদাহরণ দেখুন
In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form
হিসাবে __repr__
In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.
আমরা __repr__
সুবিধামত ফলাফলগুলিতে পাটিগণিত অপারেশন করতে পারি ।
In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)
যদি অপারেশন প্রয়োগ করা হয় __str__
In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'
ত্রুটি ছাড়া কিছুই দেয় না Return
আরেকটি উদাহরণ.
In [36]: str('string_body')
Out[36]: 'string_body' # in string form
In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside
আশা করি এটি আরও উত্তর অনুসন্ধানের জন্য কংক্রিট ভিত্তি তৈরিতে আপনাকে সহায়তা করবে।
__str__
স্ট্রিং অবজেক্ট অবশ্যই দিতে হবে যেখানে __repr__
কোনও পাইথন এক্সপ্রেশন ফিরে আসতে পারে।__str__
প্রয়োগটি অনুপস্থিত থাকে তবে __repr__
ফাংশনটি ফ্যালব্যাক হিসাবে ব্যবহৃত হয়। __repr__
ফাংশন বাস্তবায়ন অনুপস্থিত থাকলে কোনও ফলব্যাক নেই।__repr__
ফাংশনটি স্ট্রিংয়ের অবজেক্টের প্রতিনিধিত্ব করে, তবে আমরা __str__
ফাংশনটি প্রয়োগ করতে পারি না ।সূত্র: https://www.jorterdev.com/22460/python-str-repr-funtions