වස්තු නාමයකට පෙර තනි සහ ද්විත්ව අවධාරනයක තේරුම කුමක්ද?


1319

පයිතන් හි වස්තුවක නමට පෙර ප්‍රමුඛ අවධාරනය කිරීමක් සහ ඒ දෙක අතර වෙනස පැහැදිලි කිරීමට යමෙකුට හැකිද?

එසේම, අර්ථය ඇති වස්තුව විචල්‍යයක්, ශ්‍රිතයක්, ක්‍රමයක් යනාදිය වේවා එම අර්ථය එලෙසම පවතීද?


3
වෙනත් ත්‍රෙඩ් එකකින්
ඇන්ටන්

Answers:


1181

තනි යටි ලකුණු

පංතියක, ප්‍රමුඛ අවධාරනය සහිත නම්, හුදෙක් වෙනත් ක්‍රමලේඛකයන්ට ඇඟවීම වන්නේ ගුණාංගය හෝ ක්‍රමය පුද්ගලික වීමට අදහස් කරන බවයි. කෙසේ වෙතත්, නමෙන්ම විශේෂ කිසිවක් සිදු නොවේ.

PEP-8 උපුටා දැක්වීමට :

_single_leading_underscore: දුර්වල "අභ්‍යන්තර භාවිතය" දර්ශකය. උදා: from M import *අවධාරනයකින් ආරම්භ වන වස්තු ආනයනය නොකරයි.

ද්විත්ව යටි ලකුණු (නම මැන්ග්ලිං)

සිට සඳහා python ලේඛන :

පෝරමයේ ඕනෑම හඳුනාගැනීමක් __spam(අවම වශයෙන් ප්‍රමුඛ යටි ඉරි දෙකක්, අවම වශයෙන් එක් පසුපසින් අවධාරනය කරයි) පෙළ වෙනුවට ආදේශ කරනු ලැබේ _classname__spam, එහිදී classnameප්‍රමුඛ පෙළේ යටි ඉරි (ය) සහිත වත්මන් පන්තියේ නම ඉවත් කර ඇත. හඳුනාගැනීමේ සින්ටැක්ටික් පිහිටීම නොසලකා මෙම මැන්ග්ලිං සිදු කරනු ලැබේ, එබැවින් එය පන්ති-පෞද්ගලික උදාහරණ සහ පන්ති විචල්‍යයන්, ක්‍රම, ගෝලීය තුළ ගබඩා කර ඇති විචල්‍යයන් සහ අවස්ථාවන්හි ගබඩා කර ඇති විචල්‍යයන් පවා අර්ථ දැක්වීමට භාවිතා කළ හැකිය. වෙනත් පංතිවල අවස්ථා මත මෙම පන්තියට පුද්ගලිකයි.

එකම පිටුවකින් අනතුරු ඇඟවීමක්:

ව්‍යුත්පන්න පංති මගින් නිර්වචනය කරන ලද නිදර්ශන විචල්‍යයන් ගැන කරදර නොවී හෝ පන්තියෙන් පිටත කේත මඟින් නිදර්ශන විචල්‍යයන් සමඟ සම්බන්ධ නොවී “පුද්ගලික” නිදර්ශන විචල්‍යයන් සහ ක්‍රම නිර්වචනය කිරීමට පන්තිවලට පහසු ක්‍රමයක් ලබා දීමට නම මැන්ග්ලිං අදහස් කෙරේ. මැන්ග්ලිං නීති බොහෝ දුරට සැලසුම් කර ඇත්තේ අනතුරු වළක්වා ගැනීම සඳහා බව සලකන්න; අධිෂ් soul ානශීලී ආත්මයකට පුද්ගලිකව සලකන විචල්‍යයකට ප්‍රවේශ වීමට හෝ වෙනස් කිරීමට තවමත් හැකිය.

උදාහරණයක්

>>> class MyClass():
...     def __init__(self):
...             self.__superprivate = "Hello"
...             self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}

17
පන්තියේ නොමැති යටි ඉරි 2 ක් සමඟ ප්‍රකාශිත විචල්‍ය නමක් තිබේ නම් කුමක් කළ යුතුද? එය සාමාන්‍ය විචල්‍යයක් පමණයි නේද?
ධරව් රාමනි

109
මෙම පිළිතුර අතිශයින්ම නොමඟ යවන සුළුය, මන්දයත් ඩන්ඩර්ස්කෝර් "සුපිරි පුද්ගලික" යන ගුණාංග සෑදීම සඳහා භාවිතා කරන බව පා er කයා විශ්වාස කරයි. රේමන්ඩ් හෙට්ටින්ගර් විසින් පැහැදිලි කරන ලද පරිදි මෙය එසේ නොවේ , ඩන්ඩර්ස්කෝර් සාමාජිකයන් පෞද්ගලිකව සලකුණු කිරීම සඳහා වැරදි ලෙස භාවිතා කරන අතර එය පෞද්ගලිකව ප්‍රතිවිරුද්ධ ලෙස නිර්මාණය කර ඇත.
මාකස් මෙස්කානන්

15
Ark මාකස් මෙස්කානන් මම එකඟ නොවෙමි, පිළිතුර පැහැදිලිවම සඳහන් කරන්නේ පන්ති-පෞද්ගලික විචල්‍යයන් සහ ක්‍රමවේදයන් සඳහා ඩන්ඩර්ස්කෝරයක් භාවිතා කිරීමයි. ඩන්ඩර්ස්කෝර් නිර්මාණය කර ඇත්තේ මෙම ක්‍රම සහ විචල්‍යයන් උප පංති මගින් පහසුවෙන් නැවත ලිවීමට (ඒවා ප්‍රසිද්ධියට පත් කිරීමට) වන අතර, ඩන්ඩර්ස්කෝර් භාවිතය එම පන්තිය තුළ භාවිතා කිරීම සඳහා පුද්ගලික අවස්ථාවක් ආරක්ෂා කරයි.
arewm

8
Ark මාකස් මෙස්කානන්: සුපිරි පන්තියට නොගැලපීමකින් තොරව සුපිරි පන්තියට සමාන නම් භාවිතා කිරීමට උප පංතිවලට නිදහස ඇත - වෙනත් වචන වලින් කිවහොත්, සුපිරි පන්තියේ ඩන්ඩර් නම් තමාටම පෞද්ගලික වේ.
ඊතන් ෆුරමන්

6
තනි අවධාරනයකට, පිළිතුර "නමෙන් විශේෂ කිසිවක් කර නැත" යනුවෙන් පවසන නමුත් පසුව from M import *එය වෙනස් ආකාරයකින් සලකයි ... එබැවින් විශේෂ දෙයක් සිදු වේ ...
flow2k

314

මෙතෙක් ලබා දී ඇති විශිෂ්ට පිළිතුරු නමුත් සමහර තොරතුරු අතුරුදහන්. තනි ප්‍රමුඛ අවධාරණයක් හරියටම සම්මුතියක් පමණක් නොවේ : ඔබ භාවිතා කරන්නේ නම් from foobar import *සහ මොඩියුලය ලැයිස්තුවක් foobarනිර්වචනය නොකරන්නේ __all__නම්, මොඩියුලයෙන් ආනයනය කරන ලද නම් වලට ප්‍රමුඛ අවධාරණයක් ඇති අය ඇතුළත් නොවේ . මෙම නඩුව තරමක් අපැහැදිලි කොනක් බැවින් එය බොහෝ දුරට සමුළුවක් යැයි කියමු ;-).

ප්රධාන-underscore සමුළුව පුළුල් ලෙස පමණක් නො භාවිතා පෞද්ගලික නම්, පමණක් නොව, C ++ ගැටලුවක් වනු ඇත දේ සඳහා ආරක්ෂිත අය - උදාහරණයක් ලෙස, ක්රම නම් සම්පූර්ණයෙන්ම බව උප වර්ගිකරණයන් (පවා අය විසින් ඉක්මවනු කිරීමට බලාපොරොත්තු වන ඇති දී සිට ඉක්මවනු කිරීමට මූලික පංතිය ඔවුන් raise NotImplementedError! -) බොහෝ විට තනි-ප්‍රමුඛ-අවධාරනය කරන නම් වන අතර එම ක්‍රමයේ (හෝ උප පංති) උදාහරණ භාවිතා කරමින් කේතයට ඇඟවුම් කරන්නේ ක්‍රම කෙලින්ම කැඳවීමට අදහස් නොකරන බවයි.

උදාහරණයක් ලෙස, එක් ආනයන පෝලිමේ, FIFO වඩා වෙනස් පෙළ ගැසුණු විනය සමග නූල්-ආරක්ෂිත පෝලිමේ කිරීමට, උප වර්ගිකරණයන් Queue.Queue, සහ එවැනි ක්රම පාගා දමයි _getහා _put; "සේවාදායක කේතය" කිසි විටෙකත් එම ("කොකු") ක්‍රම හඳුන්වන්නේ නැත, නමුත් ("සංවිධානාත්මක") වැනි පොදු ක්‍රම putසහ get(මෙය අච්චු ක්‍රම සැලසුම් රටාව ලෙස හැඳින්වේ - උදා: වීඩියෝවක් මත පදනම් වූ රසවත් ඉදිරිපත් කිරීමක් සඳහා මෙහි බලන්න. පිටපතෙහි සාරාංශ එකතු කිරීමත් සමඟ මෙම විෂය පිළිබඳ මගේ කතාවක).

සංස්කරණය කරන්න: සාකච්ඡා විස්තරයේ ඇති වීඩියෝ සබැඳි දැන් බිඳී ඇත. ඔබට පළමු වීඩියෝ දෙක මෙතැනින් සහ මෙතැනින් සොයාගත හැකිය .


1
එසේ නම් එය භාවිතා කිරීම _var_nameහෝ භාවිතා කිරීම var_name+ තීරණය කරන්නේ __all__කෙසේද?
එන්ඩොලිත්

3
@endolith ඔබේ කේතය පා er කයාට මෙය භාවිතා නොකළ යුතු බවට සං signal ා කිරීම සඳහා ප්‍රමුඛ අවධාරනය භාවිතා කරන්න (උදා: ඔබ එය 2.0 අනුවාදයෙන් හෝ 1.1 කින් වෙනස් කළ හැකි නිසා); __all__ඔබට මොඩියුලය from spam import *මිත්‍රශීලී කිරීමට අවශ්‍ය සෑම විටම පැහැදිලිව භාවිතා කරන්න (අන්තර්ක්‍රියාකාරී පරිවර්තකය ඇතුළුව). එබැවින් බොහෝ විට පිළිතුර දෙකම වේ.
abarnert

Lex ඇලෙක්ස් මාර්ටෙලි මෙම ආනයන ආශ්‍රිත රීතිය නීත්‍යානුකූලව ඩොක්ස් හෝ වෙනත් තැනක සාකච්ඡා කර තිබේද?
වික්‍රොබොට්

1
මම C ++ ප්‍රතිසමයට කැමතියි. පළමුවෙන්ම, මිනිසුන් _ පුද්ගලිකව අමතන විට මම එයට අකමැතියි . පැහැදිලිවම මම කතා කරන්නේ ප්‍රතිසම ගැනයි, මන්ද පයිතන්හි කිසිවක් සැබවින්ම පුද්ගලික නොවන බැවිනි. අර්ථ නිරූපණයට කිමිදීමේදී මම කියන්නේ _ජාවා හි ප්‍රොජෙක්ට් කර ඇති බැවින් අපට ජාවාගේ ආරක්‍ෂාව සමඟ ගැටගැසිය හැකි බවයි. පැකේජය මොඩියුලය සමඟ ප්‍රතිස්ථාපනය කරන්න PEP8 දැනටමත් අපට පවසන පරිදි _එය *ආනයන ගැන කතා කිරීමේදී සම්මුතියක් පමණක් නොවන අතර එහි ඔබ සතුව ඇත. පංතියක් තුළ හඳුනාගැනීම් ගැන කතා කරන විට අනිවාර්යයෙන්ම __ජාවාගේ පෞද්ගලිකත්වයට සමාන වේ .
මාරියස් මුකෙනිකු

2
යහපත් පිළිතුරක් වන අතර, එය ද දැඩි ලෙස ස්වයං ප්‍රවර්ධනයකි.
දෙමුහුන් වෙබ් dev

309

__foo__: මෙය සම්මුතියක් පමණි, පයිතන් පද්ධතියට පරිශීලක නාම සමඟ නොගැලපෙන නම් භාවිතා කිරීමට මාර්ගයකි.

_foo: මෙය සම්මුතියක් පමණි, විචල්‍යය පුද්ගලික බව පෙන්වීමට ක්‍රමලේඛකයාට මාර්ගයකි (පයිතන්හි අර්ථය කුමක් වුවත්).

__foo: මෙයට සැබෑ අරුතක් ඇත: පරිවර්තකයා මෙම නම _classname__fooවෙනත් පන්තියක සමාන නමක් සමඟ නොගැලපෙන බව සහතික කිරීමේ ක්‍රමයක් ලෙස ප්‍රතිස්ථාපනය කරයි .

පයිතන් ලෝකයේ වෙනත් කිසිම ආකාරයක අවධාරනයකට අර්ථයක් නැත.

මෙම සම්මුතීන් තුළ පන්තිය, විචල්ය, ගෝලීය යනාදිය අතර වෙනසක් නොමැත.


6
__fooකුතුහලයෙන් යුතුව පැමිණියේය . වෙනත් පංති සමඟ සමාන ක්‍රම නාම සමඟ එය අතිච්ඡාදනය වන්නේ කෙසේද? මම අදහස් කළේ ඔබට තවමත් එයට පිවිසිය යුතු බවයි instance.__foo()(එය පරිවර්තකයා විසින් නම් නොකළේ නම්), හරිද?
බිබාස් දෙබ්නාත්

83
මේ මිනිහා රාජ්යයන් from module import *underscore-උපසර්ගය වස්තූන් ආනයන නැහැ. එබැවින් _fooඑය සම්මුතියකට වඩා වැඩි ය.
dotancohen

4
Ib බිබාස්: පංතියේ Bඋප පංති පන්තිය Aසහ දෙකම ක්‍රියාත්මක කරන්නේ foo()නම් B.foo(), එයින් .foo()උරුම වූ ඒවා අභිබවා යයි A. නිදසුනක් Bසඳහා ප්‍රවේශ විය හැක්කේ B.foo(), හැරෙන්නට පමණි super(B).foo().
naught101

3
සඳහා __dunder__එය සමහර විට සමහර අවස්ථාවන්හි දී පමණක් රීතිය වඩා ටිකක් වැඩියෙන් එසේ (බලන්න නම්, ගම්ය යාතිකා, එම අවස්ථාවේ ශබ්ද කෝෂය මඟ විශේෂ ක්රමය විමසුම් datamodel කොටස).
wim

210

._variable අර්ධ පුද්ගලික වන අතර එය සම්මුතිය සඳහා පමණක් අදහස් කෙරේ

.__variableබොහෝ විට වැරදියට සුපිරි පුද්ගලික ලෙස සලකනු ලබන අතර, එහි සැබෑ අරුත වන්නේ අහම්බෙන් ප්‍රවේශ වීම වැළැක්වීම සඳහා නාමකරණය කිරීම පමණි [1].

.__variable__ සාමාන්‍යයෙන් බිල්ඩින් ක්‍රම හෝ විචල්‍යයන් සඳහා වෙන් කර ඇත

.__mangledඔබට මංමුලා සහගතව අවශ්‍ය නම් ඔබට තවමත් විචල්‍යයන්ට ප්‍රවේශ විය හැකිය . ද්විත්ව අවධාරනය වන්නේ නාමමාත්‍ර හෝ නැවත නම් කිරීම වැනි විචල්‍යය වැනි දෙයකට යinstance._className__mangled

උදාහරණයක්:

class Test(object):
    def __init__(self):
        self.__a = 'a'
        self._b = 'b'

>>> t = Test()
>>> t._b
'b'

t._b ප්‍රවේශ විය හැක්කේ එය සම්මුතියෙන් පමණක් සැඟවී ඇති බැවිනි

>>> t.__a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Test' object has no attribute '__a'

t .__ a සොයාගත නොහැකි වූයේ එය නාමකරණය නිසා තවදුරටත් නොපවතින බැවිනි

>>> t._Test__a
'a'

instance._className__variableද්විත්ව අවධාරනය කළ නම වෙනුවට ප්‍රවේශ වීමෙන් ඔබට සැඟවුණු අගයට ප්‍රවේශ විය හැකිය


නමුත් "__a" පන්ති විචල්‍යයක් නම්, ඔබට පයිතන් ඩොක්ස් හි උපදෙස් සමඟ පවා එයට පිවිසිය නොහැක ..
විටාලි ටර්සිව්

උරුමය සම්බන්ධයෙන් ද්විත්ව අවධාරනය කිරීමේ උදාහරණයකින් කරුණාකර ඔබේ පිළිතුර යාවත්කාලීන කළ හැකිද?
විචල්‍යය

118

ආරම්භයේ දී තනි අවධාරනය:

පයිතන්ට සැබෑ පුද්ගලික ක්‍රම නොමැත. ඒ වෙනුවට, ක්‍රමයක් හෝ ආරෝපණ නාමයක් ආරම්භයේ දී අවධාරනය කරන්නේ ඔබ මෙම ක්‍රමයට ප්‍රවේශ නොවිය යුතු බවයි, මන්ද එය API හි කොටසක් නොවන බැවිනි.

class BaseForm(StrAndUnicode):

    def _get_errors(self):
        "Returns an ErrorDict for the data provided for the form"
        if self._errors is None:
            self.full_clean()
        return self._errors

    errors = property(_get_errors)

(මෙම කේත ස්නිපටය ලබාගෙන ඇත්තේ ජැන්ගෝ ප්‍රභව කේතයෙන් ය: django / form / form.py). මෙම කේතයේ, errorsපොදු දේපළකි, නමුත් මෙම දේපල _get_errors යනුවෙන් හඳුන්වන ක්‍රමය "පුද්ගලික" වේ, එබැවින් ඔබ එයට ප්‍රවේශ නොවිය යුතුය.

ආරම්භයේ අවධාරනය දෙකක්:

මෙය විශාල ව්‍යාකූලත්වයක් ඇති කරයි. පුද්ගලික ක්‍රමයක් නිර්මාණය කිරීම සඳහා එය භාවිතා නොකළ යුතුය. ඔබේ ක්‍රමය උප පංතියකින් අභිබවා යාම හෝ අහම්බෙන් ප්‍රවේශ වීම වළක්වා ගැනීමට එය භාවිතා කළ යුතුය. උදාහරණයක් බලමු:

class A(object):
    def __test(self):
        print "I'm a test method in class A"

    def test(self):
        self.__test()

a = A()
a.test()
# a.__test() # This fails with an AttributeError
a._A__test() # Works! We can access the mangled name directly!

ප්‍රතිදානය:

$ python test.py
I'm test method in class A
I'm test method in class A

දැන් B උප කාණ්ඩයක් සාදා __test ක්‍රමය සඳහා අභිරුචිකරණය කරන්න

class B(A):
    def __test(self):
        print "I'm test method in class B"

b = B()
b.test()

ප්‍රතිදානය වනු ඇත ....

$ python test.py
I'm test method in class A

අප දැක ඇති පරිදි, A.test () අප බලාපොරොත්තු වන පරිදි B .__ පරීක්ෂණ () ක්‍රම ඇමතුවේ නැත. නමුත් ඇත්ත වශයෙන්ම, __ සඳහා නිවැරදි හැසිරීම මෙයයි. __Test () යනුවෙන් හැඳින්වෙන ක්‍රම දෙක ස්වයංක්‍රීයව _A__test () සහ _B__test () ලෙස නම් කර ඇත, එබැවින් ඒවා අහම්බෙන් අභිබවා නොයයි. ඔබ __ වලින් ආරම්භ වන ක්‍රමයක් නිර්මාණය කරන විට එයින් අදහස් වන්නේ එය කිසිවෙකුට අභිබවා යාමට ඔබට අවශ්‍ය නැති බවත්, ඔබ අදහස් කරන්නේ එය එහි පන්තියේ සිටම ප්‍රවේශ කිරීමට පමණක් බවත්ය.

ආරම්භයේ සහ අවසානයේ අවධාරනය දෙකක්:

අපි වැනි ක්‍රමයක් දුටු විට __this__එය අමතන්න එපා. මෙය පයිතන් ඇමතීමට අදහස් කරන ක්‍රමයක් මිස ඔබ නොවේ. අපි බලමු:

>>> name = "test string"
>>> name.__len__()
11
>>> len(name)
11

>>> number = 10
>>> number.__add__(40)
50
>>> number + 50
60

මෙම මැජික් ක්‍රම හඳුන්වන ක්‍රියාකරු හෝ ස්වදේශීය ශ්‍රිතයක් සෑම විටම පවතී. සමහර විට එය විශේෂිත අවස්ථාවන්හිදී කොකු පයිතන් ඇමතුමක් පමණි. නිදසුනක් ලෙස __init__()හැඳින්වෙන්නේ වස්තුව නිර්මාණය කිරීමෙන් පසුව __new__()නිදර්ශනය තැනීමට කැඳවූ විට ...

අපි උදාහරණයක් බලමු ...

class FalseCalculator(object):

    def __init__(self, number):
        self.number = number

    def __add__(self, number):
        return self.number - number

    def __sub__(self, number):
        return self.number + number

number = FalseCalculator(20)
print number + 10      # 10
print number - 20      # 40

වැඩි විස්තර සඳහා, PEP-8 මාර්ගෝපදේශය බලන්න . තවත් මැජික් ක්‍රම සඳහා, මෙම PDF බලන්න .


1
මෙම පිළිතුර මා විසින්ම සංස්කරණය කිරීමෙන් පසුව, මම වඩාත් කැමති stackoverflow.com/a/8689983/1048186
ජොෂියා

"අප දැක ඇති පරිදි, A.test () B .__ පරීක්ෂණ () ක්‍රම" ලෙස හැඳින්වූයේ නැත - ඔබ A.test () ලෙස හැඳින්වූයේ කොහෙන්ද?
විචල්‍යය

18

සමහර විට ඔබ සතුව ප්‍රමුඛ පෙළේ අවධාරනයක් සහිත ටුපල් එකක් ලෙස පෙනේ

def foo(bar):
    return _('my_' + bar)

මෙම අවස්ථාවෙහිදී, සිදුවෙමින් පවතින්නේ _ () යනු පෙදෙසි මත පදනම්ව නිසි භාෂාවට ඇතුළත් කිරීම සඳහා පෙළ මත ක්‍රියාත්මක වන ප්‍රාදේශීයකරණ ශ්‍රිතයක් සඳහා අන්වර්ථයකි. උදාහරණයක් ලෙස, ස්පින්ක්ස් මෙය කරන අතර ආනයන අතර ඔබ සොයා ගනු ඇත

from sphinx.locale import l_, _

සහ sphinx.locale හි _ () සමහර ප්‍රාදේශීයකරණ ශ්‍රිතයේ අන්වර්ථයක් ලෙස පවරා ඇත.


12

බොහෝ අය රේමන්ඩ්ගේ කතාවට යොමු වන බැවින් , ඔහු පැවසූ දේ ලිවීමෙන් මම එය ටිකක් පහසු කරමි.

ද්විත්ව අවධාරනයේ අරමුණ පෞද්ගලිකත්වය ගැන නොවේ. අභිප්‍රාය වූයේ එය හරියටම මේ ආකාරයට භාවිතා කිරීමයි

class Circle(object):

    def __init__(self, radius):
        self.radius = radius

    def area(self):
        p = self.__perimeter()
        r = p / math.pi / 2.0
        return math.pi * r ** 2.0

    def perimeter(self):
        return 2.0 * math.pi * self.radius

    __perimeter = perimeter  # local reference


class Tire(Circle):

    def perimeter(self):
        return Circle.perimeter(self) * 1.25

එය ඇත්ත වශයෙන්ම පෞද්ගලිකත්වයට ප්‍රතිවිරුද්ධ දෙයකි. එමඟින් ඔබේ උප පංති අනෙක් ක්‍රම කඩ නොකර ඕනෑම එක් ක්‍රමයක් අභිබවා යාමට නිදහස ලබා දෙයි .

ඔබ දේශීය සඳහනක් තබා නැහැ කියන්න perimeterතුළ Circle. දැන්, ව්‍යුත්පන්න පංතියක් ස්පර්ශ නොකර Tireක්‍රියාත්මක කිරීම අභිබවා යයි . ඔබ අමතන විට , න්‍යායිකව එය තවමත් ගණනය කිරීම සඳහා භාවිතා කළ යුතුය , නමුත් යථාර්ථයේ දී එය භාවිතා කරයි , එය අපේක්ෂිත හැසිරීම නොවේ. කවය තුළ අපට දේශීය යොමු කිරීමක් අවශ්‍ය වන්නේ එබැවිනි.perimeterareaTire(5).area()Circle.perimeterTire.perimeter

නමුත් ඒ __perimeterවෙනුවට ඇයි _perimeter? _perimeterතවමත් ව්‍යුත්පන්න පන්තියට අභිබවා යාමට අවස්ථාවක් ලබා දෙන නිසා :

class Tire(Circle):

    def perimeter(self):
        return Circle.perimeter(self) * 1.25

    _perimeter = perimeter

ද්විත්ව අවධාරනයන්ට නම මැන්ග්ලිං ඇත, එබැවින් මව් පංතියේ දේශීය යොමු කිරීම ව්‍යුත්පන්න පන්තියේ අභිබවා යාමට ඇති ඉඩ ඉතා අඩුය. මේ අනුව " ඔබේ උප පංති අනෙක් ක්‍රම කඩ නොකර ඕනෑම එක් ක්‍රමයක් අභිබවා යාමට නිදහස් කරයි ".

ඔබේ පන්තියට උරුම නොවන්නේ නම්, හෝ ක්‍රමවේදය ඉක්මවා යාමෙන් කිසිවක් බිඳෙන්නේ නැත, එවිට ඔබට අවශ්‍ය නොවේ __double_leading_underscore.


1
ස්තූතියි, විනිවිදකය නිසියාකාරව දර්ශනය නොවූ නිසා මගේ කේතය අසමත් වන්නේ මන්දැයි මම නොසිතමි.
cgte

11

කිරීමට Accroding https://dbader.org/blog/meaning-of-underscores-in-python

  • තනි ප්‍රමුඛ අන්ඩර්ස්කෝර් (_වර්) : නමක් සඳහන් කිරීමේ සම්මුතිය අභ්‍යන්තර භාවිතය සඳහා අදහස් කෙරේ. සාමාන්‍යයෙන් පයිතන් පරිවර්තකය (වයිල්ඩ්කාඩ් ආනයනය හැර) බලාත්මක නොකරන අතර එයින් අදහස් කරන්නේ ක්‍රමලේඛකයාට පමණක් ඉඟියක් ලෙසය.
  • තනි ලුහුබැඳීම් යටි ලකුණු (var_) : පයිතන් මූල පද සමඟ ගැටුම් වළක්වා ගැනීම සඳහා සම්මුතිය භාවිතා කරයි.
  • ද්විත්ව ප්‍රමුඛ අන්ඩර්ස්කෝර් (__ var) : පන්ති සන්දර්භයක් තුළ භාවිතා කරන විට මැන්ග්ලිං නම් කරයි. පයිතන් පරිවර්තකය විසින් බලාත්මක කරනු ලැබේ.
  • ද්විත්ව නායකත්වය සහ පසුපස යටි ලකුණු (__ var__) : පයිතන් භාෂාව මගින් අර්ථ දක්වා ඇති විශේෂ ක්‍රම දක්වයි. ඔබේම ගුණාංග සඳහා මෙම නම් කිරීමේ යෝජනා ක්‍රමයෙන් වළකින්න.
  • තනි යටි ලකුණු (_) : සමහර විට තාවකාලික හෝ නොවැදගත් විචල්‍යයන් සඳහා නමක් ලෙස භාවිතා කරයි (“ගණන් නොගන්න”). එසේම: පයිතන් REPL හි අවසාන ප්‍රකාශනයේ ප්‍රති result ලය.

8

යමෙකුට විචල්‍ය කියවීමට පමණක් සෑදීමට අවශ්‍ය නම්, IMHO හොඳම ක්‍රමය වනුයේ දේපල () භාවිතා කිරීම පමණි. දේපල () සමඟ අපට දත්ත පාලනය කළ හැකිය.

class PrivateVarC(object):

    def get_x(self):
        pass

    def set_x(self, val):
        pass

    rwvar = property(get_p, set_p)  

    ronly = property(get_p) 

OP ටිකක් වෙනස් ප්‍රශ්නයක් ඇසූ බව මට වැටහී ඇති නමුත් 'පුද්ගලික විචල්‍යයන් සකසන්නේ කෙසේද' යනුවෙන් අසන තවත් ප්‍රශ්නයක් මෙම ප්‍රශ්නය සමඟ අනුපිටපතක් ලෙස සලකුණු කර ඇති බැවින්, මෙම අතිරේක තොරතුරු මෙහි එක් කිරීමට මම සිතුවෙමි.


6

විශිෂ්ට පිළිතුරු සහ සියල්ල නිවැරදි ය. මම සරල අර්ථ දැක්වීමක් සහ සරල අර්ථ දැක්වීමක් / අර්ථයක් ලබා දී ඇත.

තේරුම:

some_variable --► ඕනෑම කෙනෙකුට මෙය දැකිය හැකිය.

_some_variable --► ඕනෑම කෙනෙකුට මෙය දැකිය හැකි නමුත් එය පුද්ගලික ලෙස දැක්වීමේ සම්මුතියකි ... අනතුරු ඇඟවීමක් පයිතන් විසින් සිදු නොකෙරේ.

__some_varaible --► පයිතන් විචල්‍ය නාමය _classname__some_varaible (AKA name mangling) සමඟ ප්‍රතිස්ථාපනය කරන අතර එය එහි දෘශ්‍යතාව අඩු කරයි / සඟවයි සහ පුද්ගලික විචල්‍යයට සමාන වේ.

පයිතන් ලියකියවිලි වලට අනුව මෙහි අවංක වීමට

"වස්තුවක් ඇතුළත හැරෙන්නට ප්‍රවේශ විය නොහැකි පුද්ගලික" නිදර්ශන විචල්‍යයන් පයිතන්හි නොමැත "

උදාහරණය:

class A():
    here="abc"
    _here="_abc"
    __here="__abc"


aObject=A()
print(aObject.here) 
print(aObject._here)
# now if we try to print __here then it will fail because it's not public variable 
#print(aObject.__here)

_ _ සමහරක්_ වෙනස් කළ හැකි - .... එය දෘශ්‍යතාව අඩු කරයි / සඟවයි සහ පුද්ගලික විචල්‍යයට සමාන වේ. නැත, නම මැන්ග්ලිං යනු කාරණයයි, එය ක්‍රමය සඟවන්නේ නැත.
AMC

4

තනි ප්‍රමුඛ අවධාරනය සම්මුතියකි. නම් ආරම්භ වන්නේ තනි අවධාරනයකින් ද නැද්ද යන්න පරිවර්තකයාගේ දෘෂ්ටි කෝණයෙන් වෙනසක් නැත.

ද්විත්ව ප්රමුඛ හා අවර යටි ඉරි වැනි බිල්ට් ක්රම සඳහා යොදා __init__, __bool__ආදිය

ප්රධාන පෙළේ w / යටි ඉරි සගයන් අවර o ද්විත්ව ද, කෙසේ වෙතත්, පන්ති ක්රම ඇත සමුළුවකදී වේ කලවම් භාෂණ විසින්. විචල්යයන් හෝ මූලික ක්රියා නම් සඳහා වෙනසක් නොමැත.


3

ඔබේ ප්‍රශ්නය හොඳයි, එය ක්‍රම ගැන පමණක් නොවේ. මොඩියුලවල ඇති කාර්යයන් සහ වස්තූන් සාමාන්‍යයෙන් එක් යටි ඉරි සහිත උපසර්ගයක් ඇති අතර ඒවා දෙකකින් උපසර්ග කළ හැකිය.

නමුත් __double_underscore නම් මොඩියුලවල නම් කර නැත. සිදුවන්නේ, ඔබ මොඩියුලයකින් (මොඩියුල ආනයනයෙන් *) ආනයනය කරන්නේ නම්, එක් (හෝ වැඩි ගණනකින්) ආරම්භ වන නම් ආනයනය නොකෙරේ.


1
තව දුරටත්, එක් හෝ වැඩි ගණනකින් ආරම්භ වන නම්, පිටුපසින් දෙකක් හෝ වැඩි ගණනක් අවධාරනය කරයි, වෙනත් ඕනෑම නමක් ලෙස ක්‍රියා කරයි.
බෙන්ට්ලි 4

3

ද්විත්ව අවධාරනය කළ ගුණාංග උරුම වූ පන්තියකට බලපාන්නේ කෙසේද යන්න පිළිබඳ සරල නිදර්ශන උදාහරණයක් මෙන්න. එබැවින් පහත සැකසුම සමඟ:

class parent(object):
    __default = "parent"
    def __init__(self, name=None):
        self.default = name or self.__default

    @property
    def default(self):
        return self.__default

    @default.setter
    def default(self, value):
        self.__default = value


class child(parent):
    __default = "child"

ඔබ පසුව පයිතන් REPL හි ළමා අවස්ථාවක් නිර්මාණය කළහොත්, ඔබට පහත දැක්වේ

child_a = child()
child_a.default            # 'parent'
child_a._child__default    # 'child'
child_a._parent__default   # 'parent'

child_b = child("orphan")
## this will show 
child_b.default            # 'orphan'
child_a._child__default    # 'child'
child_a._parent__default   # 'orphan'

මෙය සමහරුන්ට පැහැදිලිව පෙනෙන්නට තිබුණත්, එය වඩාත් සංකීර්ණ පරිසරයක මා ආරක්ෂා කර ගත්තේය


3

වස්තුවක ඇතුළත හැරෙන්නට ප්‍රවේශ විය නොහැකි “පුද්ගලික” නිදර්ශන විචල්‍යයන් පයිතන්හි නොමැත. කෙසේ වෙතත්, බොහෝ පයිතන් කේතය අනුගමනය කරන සම්මුතියක් තිබේ: යටි ඉරි සහිත (උදා: _spam) සමඟ පෙර නමක් API හි පොදු නොවන කොටසක් ලෙස සැලකිය යුතුය (එය ශ්‍රිතයක්, ක්‍රමයක් හෝ දත්ත සාමාජිකයෙකු වේවා) . එය ක්‍රියාත්මක කිරීමේ විස්තරයක් ලෙස සැලකිය යුතු අතර දැනුම්දීමකින් තොරව වෙනස් විය යුතුය.

යොමුව https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references


1
_ ඊට වඩා බොහෝ සෙයින් සමාන ය. උදාහරණයක් ලෙස c # හි අභ්‍යන්තරය පසුව පුද්ගලික ය. එය දෙගුණයකින් අවධාරණය කරන්නේ එය පුද්ගලිකයට වඩා බොහෝ සෙයින් සමාන වන අතර අවධාරනය කරන්නේ මම කියනුයේ පුද්ගලික බවයි.
ඉනි

1

_ සහ __ යන කරුණු ලබා ගැනීම පහසුය; අනෙක් පිළිතුරු ඒවා ඉතා හොඳින් ප්‍රකාශ කරයි. භාවිතය තීරණය කිරීම වඩා දුෂ්කර ය.

මම එය දකින ආකාරය මෙයයි:

_

ශ්‍රිතයක් පොදු භාවිතය සඳහා නොවන බව දැක්වීමට භාවිතා කළ යුතුය. මෙය සහ ආනයන සීමා කිරීම නිසා එය internalc # හි මෙන් හැසිරේ .

__

උරුම ධූරාවලිය තුළ නම ගැටීම වළක්වා ගැනීමට සහ ප්‍රමාද වීම වළක්වා ගැනීමට භාවිතා කළ යුතුය. C # හි පුද්ගලික වැනි.

==>

යමක් පොදු භාවිතය සඳහා නොවන බව ඔබට ඇඟවීමට අවශ්‍ය නම් එය protectedභාවිතයට සමාන විය යුතුය _. යමක් පොදු භාවිතය සඳහා නොවන බව ඔබට ඇඟවීමට අවශ්‍ය නම් එය privateභාවිතයට සමාන විය යුතුය __.

මෙයද මම බෙහෙවින් කැමති උපුටා දැක්වීමකි:

ගැටළුව වන්නේ පංතියක කතුවරයා නීත්‍යානුකූලව "මෙම ගුණාංගයේ / ක්‍රමයේ නම පුද්ගලික විය යුතු අතර මෙම පංතියේ අර්ථ දැක්වීමෙන් පමණක් ප්‍රවේශ විය හැකිය" යැයි සිතිය හැකි අතර __ පුද්ගලික සම්මුතිය භාවිතා කිරීමයි. නමුත් පසුකාලීනව, එම පන්තියේ පරිශීලකයෙකුට එම නමට නීත්‍යානුකූලව ප්‍රවේශය අවශ්‍ය වන උප පංතියක් සෑදිය හැකිය. එබැවින් එක්කෝ සුපිරි පන්තිය වෙනස් කළ යුතුය (එය දුෂ්කර හෝ කළ නොහැකි විය හැකිය), හෝ උප පංති කේතයට අතින් අතින් කළ හැකි නම් භාවිතා කළ යුතුය (එය කැත සහ බිඳෙන සුළුය).

නමුත් එහි ඇති ගැටළුව නම්, ඔබ ක්‍රම ඉක්මවා යන විට ඔබට අනතුරු අඟවන IDE එකක් නොමැති නම්, ඔබ වැරදීමකින් මූලික පන්තියකින් ක්‍රමයක් ඉක්මවා ගොස් ඇත්නම් දෝෂය සොයා ගැනීම ඔබට යම් කාලයක් ගතවනු ඇති බවයි.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.