Answers:
ඇලෙක්ස් හොඳින් සාරාංශ කළ නමුත් පුදුමයට කරුණක් නම් එය ඉතා සංක්ෂිප්ත ය.
පළමුව, ඇලෙක්ස්ගේ ලිපියේ ප්රධාන කරුණු නැවත අවධාරණය කිරීමට මට ඉඩ දෙන්න :
__repr__
ඉලක්කය නිසැක ය__str__
ඉලක්කය කියවිය හැකි වීමයි__str__
භාවිතා අඩංගු වස්තූන් '__repr__
පෙරනිමි ක්රියාත්මක කිරීම නිෂ් .ල ය
මෙය බොහෝ දුරට පුදුමයට කරුණක් වන්නේ පයිතන්ගේ පෙරනිමිති තරමක් ප්රයෝජනවත් වන බැවිනි. කෙසේ වෙතත්, මෙම අවස්ථාවේ දී, පෙරනිමියක් තිබීම __repr__
පහත පරිදි ක්රියා කරයි:
return "%s(%r)" % (self.__class__, self.__dict__)
(උදාහරණයක් ලෙස, වස්තූන් එකිනෙක ගැන සඳහන් කරන්නේ නම් අනන්ත පුනරාවර්තනයකට පිවිසීමට පහසු නැත). ඉතින් පයිතන් එළියට එනවා. එක් පෙරනිමියක් සත්ය බව සලකන්න: __repr__
අර්ථ දක්වා ඇත්නම් සහ __str__
එසේ නොවේ නම්, වස්තුව හැසිරෙනු ඇත __str__=__repr__
.
මෙයින් අදහස් කරන්නේ, සරල වචන වලින්: ඔබ ක්රියාත්මක කරන සෑම වස්තුවකටම පාහේ වස්තුව __repr__
තේරුම් ගැනීමට භාවිතා කළ හැකි ක්රියාකාරීත්වයක් තිබිය යුතුය . ක්රියාත්මක __str__
කිරීම අත්යවශ්ය නොවේ: ඔබට “ලස්සන මුද්රණ” ක්රියාකාරීත්වයක් අවශ්ය නම් එය කරන්න (උදාහරණයක් ලෙස වාර්තා උත්පාදකයක් භාවිතා කරයි).
පරමාර්ථය __repr__
නිසැක ය
මට වහාම එළියට පැමිණ එය කියන්නට ඉඩ දෙන්න - මම නිදොස් කරන්නන් විශ්වාස නොකරමි. කිසිදු නිදොස් කිරීමක් භාවිතා කරන්නේ කෙසේදැයි මම නොදනිමි, කිසි විටෙකත් බැරෑරුම් ලෙස භාවිතා කර නැත. තව දුරටත්, නිදොස්කරණය කරන්නන්ගේ විශාල දෝෂය ඔවුන්ගේ මූලික ස්වභාවය බව මම විශ්වාස කරමි - මා විසින් නිදොස්කරණය කරන ලද බොහෝ අසාර්ථකත්වයන් බොහෝ කලකට පෙර, දුර .ත මන්දාකිනියක සිදුවිය. මෙයින් අදහස් කරන්නේ, ආගමික උද්යෝගයෙන්, දැව කැපීමේදී මා විශ්වාස කරන බවයි. ලොග් වීම යනු ඕනෑම හොඳ ගිනි හා අමතක වූ සේවාදායක පද්ධතියක ජීව රුධිරයයි. පයිතන් ලොග් වීම පහසු කරයි: සමහර විට ව්යාපෘති විශේෂිත ආවරණ සහිතව, ඔබට අවශ්ය වන්නේ අ
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)
නමුත් ඔබ කළ යුත්තේ අවසාන පියවරයි - ඔබ ක්රියාත්මක කරන සෑම වස්තුවකටම ප්රයෝජනවත් repr එකක් ඇති බවට වග බලා ගන්න, එබැවින් එවැනි කේතයක් ක්රියා කළ හැකිය. “එවාල්” කාරණය පැමිණෙන්නේ මේ නිසා ය: ඔබට ප්රමාණවත් තොරතුරු තිබේ නම් eval(repr(c))==c
, එයින් අදහස් වන්නේ ඔබ දැනගත යුතු සියල්ල ඔබ දන්නා බවයි c
. එය ප්රමාණවත් තරම් පහසු නම්, අවම වශයෙන් නොපැහැදිලි ආකාරයකින් එය කරන්න. එසේ නොවේ නම්, c
කෙසේ හෝ ඔබට ප්රමාණවත් තොරතුරු ඇති බවට වග බලා ගන්න . මම සාමාන්යයෙන් එවාල් වැනි ආකෘතියක් භාවිතා කරමි : "MyClass(this=%r,that=%r)" % (self.this,self.that)
. ඔබට සැබවින්ම මයික්ලාස් සෑදිය හැකි බව හෝ ඒවා නිවැරදි ඉදිකිරීම් තර්ක යැයි එයින් අදහස් නොකෙරේ - නමුත් “මෙම අවස්ථාව ගැන ඔබ දැනගත යුතු සියල්ල මෙයයි” යන්න ප්රකාශ කිරීමට එය ප්රයෝජනවත් ආකාරයකි.
සටහන: මම %r
ඉහත භාවිතා කළෙමි , නැත %s
. ක්රියාවට නැංවීමේදී ඔබට සැමවිටම අවශ්ය වන්නේ repr()
[හෝ %r
හැඩතල ගැන්වීම, සමානව] __repr__
, නැතහොත් ඔබ නැවත කිරීමේ ඉලක්කය පරාජය කිරීමයි. ඔබ හඳුනා ගැනීමට හැකි වීමට අවශ්ය MyClass(3)
හා MyClass("3")
.
කිරීමේ ඉලක්කය __str__
වනුයේ හොඳින් කියවිය හැකි විය
නිශ්චිතවම, එය නිසැක වීමට අදහස් නොකෙරේ - එය සැලකිල්ලට ගන්න str(3)==str("3")
. ඒ හා සමානව, ඔබ IP සාරාංශයක් ක්රියාත්මක කරන්නේ නම්, එහි නූල් 192.168.1.1 ලෙස පෙනීම හොඳයි. දිනයක් / වේලාවක් සාරාංශයක් ක්රියාත්මක කිරීමේදී, str එක "2010/4/12 15:35:22" විය හැකිය. නිෂ් less ල ඉලක්කම් කපා දමන්න, වෙනත් පංතියක් ලෙස පෙනී සිටින්න - එය කියවීමේ හැකියාව සඳහා සහය දක්වන තාක් කල් එය වැඩිදියුණු කිරීමකි.
රුවනයකි ගේ __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__
නම් සාමාන්ය සංවර්ධකයින්ට කියවිය හැකි වස්තුවක් ඇති බැවින් SDK සංවර්ධකයින් භාවිතා කරනු ඇත . අනෙක් අතට, __repr__
SDK සංවර්ධකයින් සඳහාම වේ.
වෙනත් ආකාරයකින් සහතික කිරීම සඳහා ඔබ විශේෂයෙන් ක්රියා නොකරන්නේ නම්, බොහෝ පන්තිවලට මේ සඳහා ප්රයෝජනවත් ප්රති results ල නොමැත:
>>> 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__
, නමුත් අනෙක් අතට නොවේ.
දැන ගැනීමට වෙනත් තීරණාත්මක tidbits: __str__
ඉදි කොට මත රුවනයකි මත භාවිතා __repr__
නොව, __str__
එය අන්තර්ගත අයිතම සඳහා,. සාමාන්ය ලියකියවිලි වල ඇති වචන තිබියදීත්, සමාන වස්තුවක් තැනීම සඳහා භාවිතා __repr__
කළ eval
හැකි නූලක් බවට වස්තූන් සෑදීම ගැන කිසිවෙකු කරදර වන්නේ නැත (එය ඉතා අසීරු ය, අදාළ මොඩියුලය ඇත්ත වශයෙන්ම ආනයනය කළේ කෙසේදැයි නොදැන එය සැබවින්ම කරයි පැතලි කළ නොහැකි).
එබැවින්, මගේ අවවාදය: __str__
සාධාරණ ලෙස මානව කියවිය හැකි සහ __repr__
ඔබට හැකි තරම් සැක සහිත ලෙස අවධානය යොමු කරන්න, එමඟින් __repr__
ආපසු ලැබිය හැකි වටිනාකම ආදානය ලෙස පිළිගත හැකි බවට පත් කර ගැනීමේ නොපැහැදිලි ඉලක්කයට එය බාධා කළත් __eval__
!
eval(repr(foo))
සමාන වස්තුවකට තක්සේරු කරනවාදැයි පරීක්ෂා කරමි foo
. මොඩියුලය ආනයනය කරන්නේ කෙසේදැයි මා නොදන්නා බැවින් එය මගේ පරීක්ෂණ අවස්ථාවන්ට පිටින් ක්රියා නොකරන බව ඔබ නිවැරදිය, නමුත් මෙය අවම වශයෙන් එය කිසියම් පුරෝකථනය කළ හැකි සන්දර්භයක් තුළ ක්රියාත්මක වන බව සහතික කරයි . ප්රති result __repr__
ලය ප්රමාණවත් තරම් පැහැදිලි නම් මෙය ඇගයීමට හොඳ ක්රමයක් යැයි මම සිතමි . ඒකක පරීක්ෂණයකදී මෙය __repr__
සිදු කිරීම පන්තියේ වෙනස්කම් පහත දැක්වෙන බව සහතික කිරීමට උපකාරී වේ.
eval(repr(spam)) == spam
(අවම වශයෙන් නිවැරදි සන්දර්භය තුළ), හෝ eval(repr(spam))
මතු කරයි SyntaxError
. ඒ ආකාරයෙන් ඔබ ව්යාකූලත්වය වළක්වයි. (ඒ තියෙන්නේ පාහේ මෙම builtins සඳහා සත්ය හා stdlib බොහෝ, හැර, උදා, ආවර්තනික එහිදී ලැයිස්තු, 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))
වේ. එය කණගාටුදායක නමුත් තේරුම්ගත හැකි ය. BTW, eval(str(A.X))
ඇත්ත වශයෙන්ම ක්රියාත්මක වේ, නමුත් ඇත්ත වශයෙන්ම class A
විෂය පථයේ තිබේ නම් පමණි - එබැවින් එය බොහෝ සෙයින් ප්රයෝජනවත් නොවේ.
str
භාවිතා අංගයක් repr
නිසා [1, 2, 3]
=! ["1", "2, 3"]
.
__repr__
: සාමාන්යයෙන් evt python object නිරූපණය කිරීමෙන් එය නැවත එම වස්තුව බවට පරිවර්තනය වේ
__str__
: ඔබ සිතන ඕනෑම දෙයක් එම වස්තුව පෙළ ස්වරූපයෙන් වේ
උදා
>>> 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()
, එසේ නොමැතිනම් නිරූපණය යනු කෝණික වරහන් තුළ කොටා ඇති නූලක් වන අතර එමඟින් වස්තුවේ වර්ගය සහ අතිරේක තොරතුරු ඇතුළත් වේ. බොහෝ විට වස්තුවේ නම සහ ලිපිනය ඇතුළත් වේ.__repr__()
ක්රමයක් නිර්වචනය කිරීමෙන් පන්තියකට මෙම ශ්රිතය එහි අවස්ථාවන් සඳහා ලැබෙන දේ පාලනය කළ හැකිය .
මෙන්න str සඳහා ලියකියවිලි:
str(object='')
වස්තුවක මනාව මුද්රණය කළ හැකි නිරූපණයක් අඩංගු නූලක් ආපසු එවන්න. නූල් සඳහා, මෙය නූල් නැවත ලබා දෙයි. මෙහි ඇති වෙනස
repr(object)
නම්str(object)
සෑම විටම පිළිගත හැකි නූලක් ආපසු ලබා දීමට උත්සාහ නොකිරීමeval()
; එහි ඉලක්කය වන්නේ මුද්රණය කළ හැකි නූලක් ආපසු ලබා දීමයි. තර්කයක් ලබා දී නොමැති නම්, හිස් නූල නැවත ලබා දෙන්න''
.
පයිතන් අතර
__str__
සහ වෙනස__repr__
කුමක්ද?
__str__
("dunder (double-underscore) string" __repr__
ලෙස කියවන්න ) සහ ("dunder-repper" ("නිරූපණය" සඳහා කියවන්න)) දෙකම වස්තුවේ තත්වය මත පදනම්ව නූල් ආපසු ලබා දෙන විශේෂ ක්රම වේ.
__repr__
__str__
අස්ථානගත වී ඇත්නම් උපස්ථ හැසිරීම සපයයි .
එබැවින් යමෙකු පළමුවෙන්ම ලිවිය යුත්තේ __repr__
එය නැවත ලබා දෙන නූලෙන් සමාන වස්තුවක් නැවත ස්ථාපනය කිරීමට ඔබට ඉඩ සලසයි. උදා: eval
පයිතන් කවචයක අක්ෂර-අක්ෂර සඳහා එය ටයිප් කිරීම.
ඕනෑම වේලාවක, යමෙකුට __str__
එය අවශ්ය යැයි විශ්වාස කරන විට, පරිශීලකයාට කියවිය හැකි නූල් නිරූපණය සඳහා ලිවිය හැකිය.
__str__
ඔබ වස්තුව මුද්රණය කිරීම, හෝ එය සමත් නම් format
, str.format
හෝ str
, පසුව නම් __str__
ක්රමය, අර්ථ ක්රමය කැඳවන බව, වෙනත් ආකාරයකින්, __repr__
භාවිතා කරනු ඇත.
__repr__
මෙම __repr__
ක්රමය බිල්ඩින් ශ්රිතය මගින් හැඳින්වෙන අතර 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__
( C Python source ) වැනි දෙයක්:
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)
අපි දිවා කාලයේ වස්තුවක් මුද්රණය කරන්නේ නම්, අපට කියවිය හැකි ලස්සන (ඇත්ත වශයෙන්ම, ISO) ආකෘතියක් අපට පෙනේ. මෙය ක්රියාත්මක වන්නේ දිවා කාලයේ __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__
, නිදොස් කිරීමේ දී සංවර්ධකයින්ගේ භාවිතය සඳහා ලියා ඇති a , ඔබ ලිවීමට පෙර ලිවිය යුතුය __str__
.
ඔබට අවශ්ය __str__
වන්නේ ඔබට වස්තුවෙහි පෙළ නිරූපණයක් අවශ්ය වූ විට පමණි.
__repr__
ඔබ ලියන වස්තූන් සඳහා නිර්වචනය කරන්න, එවිට ඔබ සහ අනෙකුත් සංවර්ධකයින් එය වර්ධනය වන විට එය භාවිතා කරන විට ප්රජනනය කළ හැකි ආදර්ශයක් ඇත. __str__
ඔබට එය කියවිය හැකි මිනිස් නිරූපණයක් අවශ්ය විට නිර්වචනය කරන්න .
type(obj).__qualname__
නොවේද?
හාන්ස් පීටර් ලැන්ග්ටැන්ගන් විසින් පරිගණක විද්යාව සඳහා පයිතන් ස්ක්රිප්ටින් පොතේ 358 වන පිටුවේ එය පැහැදිලිව සඳහන් කරයි
__repr__
වස්තුව පිළිබඳ සම්පූර්ණ string නියෝජන දී අරමුණු කවරේද;__str__
මුද්රණය සඳහා කදිම string නැවත පැමිණීමට නියමිත ය.ඒ නිසා, මම ඒවා තේරුම් ගැනීමට කැමතියි
පරිශීලකයාගේ දෘෂ්ටි කෝණයෙන් මෙය පයිතන් ඉගෙන ගැනීමේදී මා කළ වරදවා වටහා ගැනීමකි.
කුඩා නමුත් හොඳ උදාහරණයක් පහත දැක්වෙන පිටුවේම ලබා දී ඇත:
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()
ලබා ගත හැකි අතර එය අනන්ත පුනරාවර්තනය ස්වයංක්රීයව වළක්වා ගැනීමට උත්සාහ කරයි ...
.
සරලව කිවහොත්:
__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)
සෑම අවංකකමකින්ම, eval(repr(obj))
කිසි විටෙකත් භාවිතා නොවේ. ඔබ එය භාවිතා කරන බව පෙනේ නම්, ඔබ නැවැත්විය යුතුය, මන්ද eval
එය භයානක වන අතර, නූල් යනු ඔබේ වස්තූන් අනුක්රමික කිරීමට ඉතා අකාර්යක්ෂම ක්රමයකි ( pickle
ඒ වෙනුවට භාවිතා කරන්න).
එබැවින්, සැකසීමට මම නිර්දේශ කරමි __repr__ = __str__
. හේතුව බව ය str(list)
ඇමතුම් repr
මූලද්රව්ය මත (මම මේ Python 3 ආමන්ත්රණය කර නැති බව Python විශාලතම නිර්මාණ එතරම්ම සාර්ථකත්වයක් එකක් වෙන්න සලකා). සත්යයක් repr
බොහෝ විට ප්රතිදානය ලෙස එතරම් ප්රයෝජනවත් නොවනු ඇත print [your, objects]
.
මෙය සුදුසුකම් ලැබීම සඳහා, මගේ අත්දැකීම් අනුව, repr
ශ්රිතයේ වඩාත්ම ප්රයෝජනවත් අවස්ථාව වන්නේ වෙනත් නූලක් තුළ නූලක් තැබීමයි (නූල් හැඩතල ගැන්වීම භාවිතා කිරීම). මේ ආකාරයෙන්, ඔබ උපුටා දැක්වීම් හෝ වෙනත් කිසිවක් ගැන කරදර විය යුතු නැත. නමුත් eval
මෙහි කිසිදු දෙයක් සිදු නොවන බව සලකන්න .
eval(repr(obj))
සනීපාරක්ෂක පරීක්ෂණයක් සහ නියමාකාර නීතියක් - මෙය මුල් වස්තුව නිවැරදිව ප්රතිනිර්මාණය කරන්නේ නම් ඔබට හොඳ __repr__
ක්රියාත්මක කිරීමක් තිබේ. ඔබ සැබවින්ම වස්තු මේ ආකාරයෙන් අනුක්රමික කිරීම අදහස් නොකෙරේ.
eval
සහජයෙන්ම භයානක නොවේ. වඩා භයානක නොවේ unlink
, open
හෝ ගොනු වෙත ලිඛිතව. අනිෂ්ට ප්රහාරයකින් අන්තර්ගතය ඇතුලත් කිරීමට අත්තනෝමතික ගොනු මාර්ගයක් භාවිතා කළ හැකි නිසා අපි ලිපිගොනු වලට ලිවීම නතර කළ යුතුද? ගොළු අය ගොළු ලෙස භාවිතා කරන්නේ නම් සියල්ල භයානක ය. මෝඩකම භයානකයි. ඩනිං-කෘගර් බලපෑම් භයානක ය. eval
ශ්රිතයක් පමණි.
සිට ක (නිල නොවන) Python විමර්ශන විකිපීඩියා, නිදහස් විශ්වකෝෂය (සංරක්ෂිත පිටපතක්) effbot ලද්දේ:
__str__
" වස්තුවක" අවිධිමත් "නූල් නිරූපණය ගණනය කරයි. මෙය __repr__
වලංගු පයිතන් ප්රකාශනයක් විය යුතු බවට වඩා වෙනස් වේ : ඒ වෙනුවට වඩාත් පහසු හෝ සංක්ෂිප්ත නිරූපණයක් භාවිතා කළ හැකිය. "
__repr__
වයිල්ඩ් පයිතන් ප්රකාශනයක් නැවත ලබා දීමට කිසිසේත් අවශ්ය නොවේ.
අනෙක් පිළිතුරු වල නැති එක් අංගයක්. පොදුවේ රටාව මෙය බව සත්යයකි:
__str__
: මිනිස් කියවිය හැකි__repr__
: සැක සහිත, සමහර විට යන්ත්ර කියවිය හැකි යeval
අවාසනාවකට මෙන්, මෙම අවකලනය දෝෂ සහිත ය, මන්ද යත්, පයිතන් REPL සහ IPython __repr__
REPL කොන්සෝලය තුළ වස්තු මුද්රණය කිරීම සඳහා භාවිතා කරන බැවිනි ( පයිතන් සහ IPython සඳහා අදාළ ප්රශ්න බලන්න ). මේ අනුව, අන්තර්ක්රියාකාරී කොන්සෝල වැඩ සඳහා ඉලක්ක කර ඇති ව්යාපෘති (උදා: නැම්පි හෝ පැන්ඩා) ඉහත නීති නොසලකා හැර __repr__
ඒ වෙනුවට මිනිසුන්ට කියවිය හැකි ක්රියාත්මක කිරීමක් ලබා දීමට පටන් ගෙන තිබේ.
Fluent Python පොතෙන් :
පයිතන් වස්තුවක් සඳහා මූලික අවශ්යතාවයක් වන්නේ තමන් විසින්ම භාවිතා කළ හැකි නූල් නිරූපණයන් සැපයීමයි, එකක් නිදොස්කරණය සහ ලොග් වීම සඳහා භාවිතා කරන අතර තවත් එකක් අවසාන පරිශීලකයින්ට ඉදිරිපත් කිරීම සඳහා ය.
විශේෂ ආකෘතීන්__repr__
සහ__str__
දත්ත ආකෘතියේ පවතින්නේ එබැවිනි .
විශිෂ් answer පිළිතුරු දැනටමත් __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))"
Python මීට උදාහරණ කියවීමේ පහසුව වැඩි unambiguity උපකාරී වන __str__
අ ඇමතුමක් tuple
අඩංගු වස්තූන් 'ඉල්ලා __repr__
එම "විධිමත්" වස්තුවක නිරූපණය. විධිමත් නිරූපණය අවිධිමත් එකකට වඩා කියවීමට අපහසු වුවද, එය දෝෂ වලට එරෙහිව නිසැක හා වඩා ශක්තිමත් ය.
__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()
result ලය කැඳවූ විට 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__
results ල මත ගණිතමය මෙහෙයුමක් අපට පහසුවෙන් කළ හැකිය .
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'
දෝෂයක් හැර අන් කිසිවක් ලබා නොදේ.
තවත් උදාහරණයක්.
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.journaldev.com/22460/python-str-repr-functions