ස්ථිතික ක්‍රමය සහ පන්ති ක්‍රමය අතර වෙනස


3590

සරසා ඇති ශ්‍රිතයක් @staticmethodහා අලංකාර කර ඇති ශ්‍රිතයක් අතර වෙනස @classmethodකුමක්ද?


12
පිරිසිදුකම සඳහා පයිතන්හි මොඩියුල මට්ටමේ ක්‍රියාකාරිත්වයන් ලෙස ස්ථිතික ක්‍රම සමහර විට වඩා හොඳය. මොඩියුල ශ්‍රිතයක් සමඟ ඔබට අවශ්‍ය ශ්‍රිතය ආනයනය කිරීම සහ අනවශ්‍ය දේ වළක්වා ගැනීම පහසුය. සින්ටැක්ස් (මම ඔබ දෙස බලන්නේ අරමුණ-සී). "කර්මාන්තශාලා රටා" කාර්යයන් නිර්මාණය කිරීම සඳහා බහුමාපක සමඟ ඒකාබද්ධව භාවිතා කළ හැකි බැවින් පන්ති ක්‍රමවලට වැඩි ප්‍රයෝජනයක් ඇත. මෙයට හේතුව පන්ති ක්‍රම මඟින් ව්‍යංග පරාමිතියක් ලෙස පන්තිය ලබා ගැනීමයි.
FistOfFury

27
tl; dr >> සාමාන්‍ය ක්‍රම සමඟ සසඳන විට ස්ථිතික ක්‍රම සහ පන්ති ක්‍රම ද පන්තිය භාවිතයෙන් ප්‍රවේශ කළ හැකි නමුත් පන්ති ක්‍රම මෙන් නොව ස්ථිතික ක්‍රම උරුමය හරහා වෙනස් කළ නොහැක.
imsrgadich

4
මාතෘකාව පිළිබඳ රේමන්ඩ් හෙටින්ගර් විසින් කරන ලද කතාව: youtube.com/watch?v=HTLu2DFOdTg
moooeeeep

වඩාත් නිවැරදිව youtube.com/watch?v=HTLu2DFOdTg&feature=youtu.be&t=2689 ඔබට අවශ්‍ය වන්නේ විකල්ප ඉදිකිරීම්කරුවන් සඳහා පන්ති ක්‍රමය පමණි. එසේ නොමැතිනම් ඔබට ස්ථිතික ක්‍රමය භාවිතා කළ හැකි අතර පංති ක්‍රමයේ වැනි ක්ලස් වෙනුවට කෙසේ හෝ වඩාත් තොරතුරු සහිත සත්‍ය “ක්ලාස්නාම්” මඟින් ඕනෑම පන්ති ගුණාංගයකට (. / Dot හරහා) පිවිසිය හැකිය
රොබට් නෝවාක්

Answers:


3142

සමහර විට උදාහරණ කේතයක් උපකාරී වනු ඇත: ඇමතුම් අත්සන් වල වෙනස සැලකිල්ලට ගන්න foo, class_fooසහ static_foo:

class A(object):
    def foo(self, x):
        print "executing foo(%s, %s)" % (self, x)

    @classmethod
    def class_foo(cls, x):
        print "executing class_foo(%s, %s)" % (cls, x)

    @staticmethod
    def static_foo(x):
        print "executing static_foo(%s)" % x    

a = A()

පහත දැක්වෙන්නේ වස්තුවක් නිදසුනක් ලෙස ක්‍රමයක් හඳුන්වන සාමාන්‍ය ක්‍රමයයි. වස්තු උදාහරණය, aපළමු තර්කය ලෙස ව්‍යංගයෙන් සම්මත වේ.

a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>,1)

පංති ක්‍රම සමඟ , වස්තුව නිදර්ශනයේ පන්තිය වෙනුවට පළමු තර්කය ලෙස ව්‍යංගයෙන් සම්මත වේ self.

a.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)

ඔබට class_fooපන්තිය භාවිතා කර ඇමතිය හැකිය. ඇත්ත වශයෙන්ම, ඔබ යම් දෙයක් පන්ති ක්‍රමයක් ලෙස අර්ථ දක්වන්නේ නම්, එය බොහෝ විට ඔබ එය පන්තියේ අවස්ථාවකට වඩා පන්තියෙන් ඇමතීමට අදහස් කරන නිසා විය හැකිය. A.foo(1)TypeError මතුකරනු ඇත, නමුත් A.class_foo(1)හොඳින් ක්‍රියා කරයි:

A.class_foo(1)
# executing class_foo(<class '__main__.A'>,1)

පංති ක්‍රම සඳහා මිනිසුන් සොයාගෙන ඇති එක් භාවිතයක් නම්, උරුම කළ හැකි විකල්ප ඉදිකිරීම්කරුවන් නිර්මාණය කිරීමයි .


ස්ථිතික ක්‍රම සමඟ , self(වස්තු උදාහරණය) හෝ cls(පන්තිය) පළමු තර්කය ලෙස ව්‍යංගයෙන් සම්මත නොවේ. ඒවා හැසිරෙන්නේ ඔබට සරල උදාහරණයකින් හෝ පන්තියකින් ඇමතිය හැකිය.

a.static_foo(1)
# executing static_foo(1)

A.static_foo('hi')
# executing static_foo(hi)

පංතිය සමඟ පන්තියට යම් තාර්කික සම්බන්ධතාවයක් ඇති කණ්ඩායම් ක්‍රියාකාරකම් සඳහා ස්ථිතික ක්‍රම භාවිතා කරයි.


fooඑය ශ්‍රිතයක් පමණි, නමුත් ඔබ ඇමතූ විට ඔබට a.fooශ්‍රිතය ලැබෙන්නේ නැත, ශ්‍රිතයේ aපළමු තර්කය ලෙස බැඳී ඇති වස්තු උදාහරණය සමඟ ශ්‍රිතයේ “අර්ධ වශයෙන් යෙදෙන” අනුවාදයක් ඔබට ලැබේ . fooතර්ක 2 ක් a.fooඅපේක්ෂා කරන අතර, තර්ක 1 ක් පමණක් අපේක්ෂා කරයි.

aබැඳී ඇත foo. පහත දැක්වෙන “බැඳී” යන යෙදුමෙන් අදහස් කරන්නේ එයයි:

print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>

සමග a.class_foo, aබැඳී නැත class_foo, ඒ වෙනුවට පන්තිය Aබැඳී ඇත class_foo.

print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>

මෙන්න, ස්ථිතික ක්‍රමයක් සමඟ, එය ක්‍රමයක් වුවද, a.static_fooකිසිදු තර්කයක් නොමැතිව හොඳ ඔලේ ශ්‍රිතයක් ලබා දෙයි. static_fooතර්ක 1 ක් අපේක්ෂා කරන අතර තර්ක 1 ක් ද a.static_fooඅපේක්ෂා කරයි.

print(a.static_foo)
# <function static_foo at 0xb7d479cc>

ඇත්ත වශයෙන්ම ඔබ ඒ වෙනුවට static_fooපංතිය සමඟ කතා කරන විට එකම දේ සිදුවේ A.

print(A.static_foo)
# <function static_foo at 0xb7d479cc>

182
ස්ථිතික ක්‍රමය භාවිතා කිරීම සඳහා අල්ලා ගැනීම කුමක්දැයි මට තේරෙන්නේ නැත. අපට සරල පංතියෙන් බැහැර ශ්‍රිතයක් භාවිතා කළ හැකිය.
ඇල්කොට්

374
L ඇල්කොට්: ශ්‍රිතයක් පන්තියට ගෙනයාමට ඔබට අවශ්‍ය විය හැකිය, මන්ද එය තර්කානුකූලව පන්තියට අයත් වේ. පයිතන් ප්‍රභව කේතයේ (උදා: බහු සැකසුම්, කැස්බෑවා, ඩිස්ට් පැකේජ), මොඩියුලයේ නාම අවකාශයෙන් තනි-අවධාරනය කරන “පුද්ගලික” කාර්යයන් “සැඟවීමට” භාවිතා කරයි. කෙසේ වෙතත්, එහි භාවිතය මොඩියුල කිහිපයකින් පමණක් සංකේන්ද්‍රණය වී ඇත - සමහර විට එය ප්‍රධාන වශයෙන් ශෛලීය දෙයක් බවට ඇඟවීමකි. මට මේ සඳහා කිසිදු උදාහරණයක් සොයාගත නොහැකි වුවද, @staticmethodඋප පංති මගින් අභිබවා යමින් ඔබේ කේතය සංවිධානය කිරීමට උදව් වනු ඇත. එය නොමැතිව ඔබට මොඩියුලයේ නාම අවකාශයේ පාවෙන ශ්‍රිතයේ ප්‍රභේද ඇත.
unutbu

15
... උදාහරණ, පන්ති හෝ ස්ථිතික ක්‍රම භාවිතා කරන්නේ කොතැනද සහ ඇයි යන්න පිළිබඳ යම් පැහැදිලි කිරීමක් සමඟ . ඔබ ඒ ගැන එක වචනයක්වත් කීවේ නැත, නමුත් OP ඒ ගැන විමසුවේ නැත.
මෙස්ට්‍රෙලියන්

106
L ඇල්කොට්: unutbu පැවසූ පරිදි, ස්ථිතික ක්‍රම යනු සංවිධානයක් / ශෛලීය ලක්ෂණයකි. සමහර විට මොඩියුලයකට බොහෝ පංති ඇති අතර සමහර උපකාරක කාර්යයන් තාර්කිකව බැඳී ඇත්තේ aa පන්තියට මිස අනෙක් ඒවාට නොවේ, එබැවින් බොහෝ “නිදහස් කාර්යයන්” සහිත මොඩියුලය “දූෂණය” නොකිරීමට එය අර්ථවත් වන අතර ස්ථිතික භාවිතා කිරීම වඩා හොඳය. පංති සහ ක්‍රියාකාරී ඩෙෆ්ස් මිශ්‍ර කිරීමේ දුර්වල ශෛලිය මත යැපීමට වඩා ක්‍රමවේදය ඒවා “සම්බන්ධ” බව පෙන්වීමට පමණි.
MestreLion

4
මේ සඳහා තවත් එක් භාවිතයක් @staticmethod- කබොල ඉවත් කිරීමට ඔබට එය භාවිතා කළ හැකිය. මම පයිතන් හි ක්‍රමලේඛන භාෂාවක් ක්‍රියාත්මක කරමි - පුස්තකාලයෙන් නිර්වචනය කරන ලද කාර්යයන් ස්ථිතික executeක්‍රමයක් භාවිතා කරයි , එහිදී පරිශීලක අර්ථ දක්වන ලද ශ්‍රිතයන්ට නිදර්ශන තර්ක අවශ්‍ය වේ (එනම් ශ්‍රිත ශරීරය). මෙම සැරසිලි කරුවා පයිචාර්ම් පරීක්ෂකගේ “භාවිතයට නොගත් පරාමිති ස්වයං” අනතුරු ඇඟවීම් ඉවත් කරයි.
ටෙවලස්

799

staticmethod එය මත හැඳින්වූ පන්ති හෝ උදාහරණයක් ගැන කිසිවක් බව ක්රමය වේ. එය සම්මත කරන ලද තර්ක ලබා ගනී, ව්‍යංග පළමු තර්කය නැත. එය මූලික වශයෙන් පයිතන් හි නිෂ් less ල ය - ඔබට ස්ථිතික ක්‍රමයක් වෙනුවට මොඩියුල ශ්‍රිතයක් භාවිතා කළ හැකිය.

classmethod , අනිත් අතට, එය පළමු වාදය ලෙස, ඉල්ලා විය එය මත හැඳින්වූ පන්ති, හෝ උදාහරණයක් පන්ති සම්මත රැඳි ක්රමයකි. පංතිය සඳහා කර්මාන්තශාලාවක් වීමට ඔබට අවශ්‍ය විට මෙය ප්‍රයෝජනවත් වේ: එය පළමු පන්තිය ලෙස හැඳින්වූ සත්‍ය පන්තිය ලබා ගන්නා බැවින්, උප පංති සම්බන්ධ වූ විට පවා ඔබට නිවැරදි පංතිය ක්ෂණිකව ක්‍රියාත්මක කළ හැකිය. dict.fromkeys()පංති ක්‍රමයක්, උප පංතියකට කැඳවූ විට උප පංතියේ උදාහරණයක් ලබා දෙන්නේ කෙසේදැයි නිරීක්ෂණය කරන්න :

>>> class DictSubclass(dict):
...     def __repr__(self):
...         return "DictSubclass"
... 
>>> dict.fromkeys("abc")
{'a': None, 'c': None, 'b': None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>> 

715
ස්ථිතික ක්‍රමයක් නිෂ් less ල නොවේ - එය ශ්‍රිතයක් පන්තියකට ඇතුළත් කිරීමේ ක්‍රමයකි (එය තර්කානුකූලව එහි අයත් බැවින්), එය පන්තියට ප්‍රවේශය අවශ්‍ය නොවන බව අඟවයි.
ටෝනි මේයර්

136
එබැවින් 'මූලික වශයෙන්' නිෂ් less ල පමණි. එවැනි සංවිධානයක් මෙන්ම පරායත්ත එන්නත් කිරීම ස්ථිතික ක්‍රම වල වලංගු භාවිතයන් වන නමුත් ජාවා වැනි පන්ති නොව මොඩියුලයන් පයිතන් හි කේත සංවිධානයේ මූලික අංග වන බැවින් ඒවායේ භාවිතය හා ප්‍රයෝජනය දුර්ලභ වේ.
තෝමස් වවුටර්ස්

40
පංතියක් තුළ හෝ එහි සිද්ධීන් සමඟ කිසිදු සම්බන්ධයක් නොමැති විට, පන්තියක් තුළ ක්‍රමයක් නිර්වචනය කිරීම පිළිබඳ තාර්කික කුමක්ද?
බෙන් ජේම්ස්

107
සමහරවිට උරුමය වෙනුවෙන්ද? නිදර්ශන ක්‍රම සහ පන්ති ක්‍රම මෙන් ස්ථිතික ක්‍රම උරුම කර ගත හැකි අතර අභිබවා යා හැකි අතර බැලීම අපේක්ෂිත පරිදි ක්‍රියාත්මක වේ (ජාවා මෙන් නොව). ස්ථිතික ක්‍රම ඇත්ත වශයෙන්ම පන්තියට හෝ නිදසුනකට කැඳවනු ලැබුවද සංඛ්‍යාත්මකව නිරාකරණය නොවේ, එබැවින් පන්තිය සහ ස්ථිතික ක්‍රම අතර ඇති එකම වෙනස ව්‍යංග පළමු තර්කයයි.
haridsv

80
ඔවුන් පිරිසිදු නාම අවකාශයක් ද නිර්මාණය කරන අතර, ශ්‍රිතය පන්තිය සමඟ යම් සම්බන්ධයක් ඇති බව තේරුම් ගැනීම පහසු කරයි.
ඉම්බ්‍රොන්ඩීර්

149

මූලික වශයෙන් @classmethodක්‍රමවේදයක් සාදන්නේ එහි පළමු තර්කය පන්තියෙන් (පන්තියේ උදාහරණයට වඩා) හැඳින්වෙන පන්තියට වන @staticmethodඅතර කිසිදු ව්‍යංග තර්ක නොමැත.


103

නිල පයිතන් ලියකියවිලි:

lassclassmethod

පංති ක්‍රමයක් මඟින් පංතිය ව්‍යංග පළමු තර්කය ලෙස ලබා ගනී. පන්ති ක්‍රමයක් ප්‍රකාශ කිරීමට, මෙම මෝඩකම භාවිතා කරන්න:

class C:
    @classmethod
    def f(cls, arg1, arg2, ...): ... 

මෙම @classmethodආකෘති පත්රය ශ්රිතයක් වේ decorator - තුළ කටයුතු අර්ථ දැක්වීම් විස්තර බලන්න කාර්යභාරය අර්ථ දැක්වීම් විස්තර සඳහා.

එය පන්තියේදී (වැනි C.f()) හෝ උදාහරණයක් ලෙස (වැනි) හැඳින්විය හැකියC().f() ) . එහි පන්තිය හැර උදාහරණය නොසලකා හරිනු ලැබේ. ව්‍යුත්පන්න පංතියක් සඳහා පන්ති ක්‍රමයක් කැඳවනු ලැබුවහොත්, ව්‍යුත්පන්න පංති වස්තුව ව්‍යංගයෙන් පළමු තර්කය ලෙස සම්මත වේ.

පන්ති ක්‍රම සී ++ හෝ ජාවා ස්ථිතික ක්‍රමවලට වඩා වෙනස් ය. ඔබට ඒවා අවශ්‍ය නම්, staticmethod()මෙම කොටසේ බලන්න.

aticstaticmethod

ස්ථිතික ක්‍රමයකට ව්‍යාජ පළමු තර්කය නොලැබේ. ස්ථිතික ක්‍රමයක් ප්‍රකාශ කිරීමට, මෙම මෝඩකම භාවිතා කරන්න:

class C:
    @staticmethod
    def f(arg1, arg2, ...): ... 

මෙම @staticmethodආකෘති පත්රය ශ්රිතයක් වේ decorator - තුළ කටයුතු අර්ථ දැක්වීම් විස්තර බලන්න කාර්යභාරය අර්ථ දැක්වීම් විස්තර සඳහා.

එය පන්තියේදී (වැනි C.f()) හෝ උදාහරණයක් ලෙස (වැනි C().f()) හැඳින්විය හැකිය . එහි පන්තිය හැර උදාහරණය නොසලකා හරිනු ලැබේ.

පයිතන්හි ස්ථිතික ක්‍රම ජාවා හෝ සී ++ හි ඇති ක්‍රම වලට සමාන වේ. වඩා දියුණු සංකල්පයක් සඳහා, classmethod()මෙම කොටසේ බලන්න.


ලියකියවිලි වල දෝෂයක් නැද්ද? ස්ථිතික ක්‍රමයේ නොවිය යුතුය: "උදාහරණය සහ එහි පන්තිය යන දෙකම නොසලකා හරිනු ලැබේ." "උදාහරණය එහි පන්තිය හැර නොසලකා හරිනු ලැබේ."
mirek

එය කපන හා අලවන දෝෂයක් විය හැකිය, නමුත් තදින් කථා කිරීම නම් ඔබ පන්තිය නොසලකා හැරියහොත් ඔබට පන්තියක් සඳහා ක්‍රමවේදයක් ඇමතිය නොහැක.
ආරොන් බෙන්ට්ලි

76

මෙන්න මෙම ප්රශ්නය පිළිබඳ කෙටි ලිපියක්

atic ස්ථිතික ක්‍රමවේදය යනු පන්තියක් තුළ අර්ථ දක්වා ඇති ශ්‍රිතයකට වඩා වැඩි දෙයක් නොවේ. පළමුව පංතිය ස්ථාපනය නොකර එය ඇමතිය හැකිය. එහි අර්ථ දැක්වීම උරුමය හරහා වෙනස් කළ නොහැකිය.

පංතිය ක්ෂණිකව නොපවතින පන්තියේ ක්‍රියාකාරිත්වය ද ඇමතිය හැකි නමුත් එහි අර්ථ දැක්වීම අනුගමනය කරන්නේ උරුමය හරහා දෙමාපිය පන්තිය නොව උප පන්තියයි. එයට හේතුව @classmethod ශ්‍රිතය සඳහා වන පළමු තර්කය සෑම විටම cls (පන්තිය) විය යුතුය.


1
ඉතින් එයින් අදහස් කරන්නේ ස්ථිතික ක්‍රමයක් භාවිතා කිරීමෙන් මම සැමවිටම දෙමාපිය පන්තියට බැඳී සිටින බවත්, පංති ක්‍රමය සමඟ මා පන්තියේ ක්‍රමය ප්‍රකාශ කරන පන්තියට බැඳී සිටින බවත් (මේ අවස්ථාවේ දී උප පංතිය) ද?
මොහාන් ගුලති

7
ස්ථිතික ක්‍රමයක් භාවිතා කිරීමෙන් ඔබ කිසිසේත් බැඳී නැත; ව්‍යාජ පළමු පරාමිතියක් නොමැත. පංති ක්‍රමය භාවිතා කිරීමෙන්, ඔබ ක්‍රමය හැඳින්වූ පන්තියේ (ඔබ එය කෙලින්ම පන්තියකට කැඳවූයේ නම්) හෝ ඔබ ක්‍රමවේදය හැඳින්වූ පන්තියේ පන්තියේ පළමු පරාමිතිය ලෙස ඔබට ලැබෙනු ඇත (ඔබ එය උදාහරණයක් ලෙස හැඳින්වූයේ නම්).
මැට් ඇන්ඩර්සන්

6
පළමු තර්කයක් ලෙස පංතියක් තිබීමෙන් පන්ති ක්‍රමවලට වෙනත් පන්ති ගුණාංග හා ක්‍රම වෙත access ජු ප්‍රවේශයක් ඇති බව පෙන්වීමට මඳක් පුළුල් කළ හැකි අතර ස්ථිතික ක්‍රම නොමැති අතර (ඒ සඳහා ඔවුන්ට MyClass.attr දෘඩ කේත කිරීම අවශ්‍ය වේ)
මෙස්ට්‍රෙලියන්

"එහි අර්ථ දැක්වීම උරුමය හරහා වෙනස් කළ නොහැකිය." පයිතන් වල කිසිම තේරුමක් නැහැ, ඔබට ස්ථිතික ක්‍රමයක් ඉක්මවා යා හැක.
cz

69

Aticstaticmethod හෝ lassClassmethod භාවිතා කරන්නේද යන්න තීරණය කිරීම සඳහා ඔබේ ක්‍රමය ඇතුළත සොයා බැලිය යුතුය. ඔබේ ක්‍රමය ඔබේ පන්තියේ වෙනත් විචල්‍යයන් / ක්‍රම වලට ප්‍රවේශ වන්නේ නම් @classmethod භාවිතා කරන්න . අනෙක් අතට, ඔබේ ක්‍රමය පන්තියේ වෙනත් කොටස් ස්පර්ශ නොකරන්නේ නම් @staticmethod භාවිතා කරන්න.

class Apple:

    _counter = 0

    @staticmethod
    def about_apple():
        print('Apple is good for you.')

        # note you can still access other member of the class
        # but you have to use the class instance 
        # which is not very nice, because you have repeat yourself
        # 
        # For example:
        # @staticmethod
        #    print('Number of apples have been juiced: %s' % Apple._counter)
        #
        # @classmethod
        #    print('Number of apples have been juiced: %s' % cls._counter)
        #
        #    @classmethod is especially useful when you move your function to other class,
        #       you don't have to rename the class reference 

    @classmethod
    def make_apple_juice(cls, number_of_apples):
        print('Make juice:')
        for i in range(number_of_apples):
            cls._juice_this(i)

    @classmethod
    def _juice_this(cls, apple):
        print('Juicing %d...' % apple)
        cls._counter += 1

classmethod සහ cls._counter vs. staticmethod සහ Apple._counter
රොබට් නෝවාක්

1
cls._countercls._counterකේතය වෙනත් පන්තියකට දැමුවද, හෝ පන්තියේ නම වෙනස් කළද තවමත් පවතී . පන්තිය Apple._counterසඳහා විශේෂිත ය Apple; වෙනත් පන්තියක් සඳහා, හෝ පන්තියේ නම වෙනස් කළ විට, ඔබ යොමු කරන ලද පන්තිය වෙනස් කළ යුතුය.
kiamlaluno

53

පයිතන්හි atstaticmethod සහ lassClassmethod අතර වෙනස කුමක්ද?

මෙම ව්‍යාජ කේතය වැනි පයිතන් කේතය ඔබ දැක ඇති අතර, එය විවිධ ක්‍රම වර්ගවල අත්සන් නිරූපණය කරන අතර ඒවා පැහැදිලි කිරීමට ලේඛනයක් සපයයි:

class Foo(object):

    def a_normal_instance_method(self, arg_1, kwarg_2=None):
        '''
        Return a value that is a function of the instance with its
        attributes, and other arguments such as arg_1 and kwarg2
        '''

    @staticmethod
    def a_static_method(arg_0):
        '''
        Return a value that is a function of arg_0. It does not know the 
        instance or class it is called from.
        '''

    @classmethod
    def a_class_method(cls, arg1):
        '''
        Return a value that is a function of the class and other arguments.
        respects subclassing, it is called with the class it is called from.
        '''

සාමාන්‍ය උදාහරණ ක්‍රමය

මුලින්ම මම පැහැදිලි කරන්නම් a_normal_instance_method. මෙය හරියටම " නිදර්ශන ක්‍රමයක් " ලෙස හැඳින්වේ " හැඳින්වේ. නිදර්ශන ක්‍රමයක් භාවිතා කරන විට, එය අර්ධ ශ්‍රිතයක් ලෙස භාවිතා කරයි (සම්පූර්ණ ශ්‍රිතයට ප්‍රතිවිරුද්ධව, ප්‍රභව කේතයෙන් බලන විට සියලු අගයන් සඳහා අර්ථ දක්වා ඇත), එනම් භාවිතා කරන විට, පළමු තර්කයේ උදාහරණය ලෙස පූර්ව නිශ්චිත වේ. වස්තුව, එහි දී ඇති සියලු ගුණාංග සමඟ. එයට වස්තුව බැඳී ඇති අවස්ථාව ඇති අතර එය වස්තුවක උදාහරණයකින් හැඳින්විය යුතුය. සාමාන්‍යයෙන්, එය උදාහරණයේ විවිධ ගුණාංග වලට ප්‍රවේශ වේ.

උදාහරණයක් ලෙස, මෙය නූලක උදාහරණයකි:

', '

අපි, උදාහරණයක් ක්රමය භාවිතා කරන්නේ නම් joinතවත් iterable එක්වන මෙම නූලක් මත, එය ඉතා පැහැදිලිව ම උදාහරණයක් ශ්රිතයක් එම iterable ලැයිස්තුව ශ්රිතයක් වීමට අමතරව, ය ['a', 'b', 'c']:

>>> ', '.join(['a', 'b', 'c'])
'a, b, c'

මායිම් ක්‍රම

පසුකාලීන භාවිතය සඳහා තිත් බැලීමක් හරහා නිදසුන් ක්‍රම බැඳිය හැකිය.

උදාහරණයක් ලෙස, මෙය str.joinක්‍රමයට උදාහරණයකට බැඳ තබයි ':':

>>> join_with_colons = ':'.join 

පසුව අපට මෙය පළමු තර්කය හා බැඳී ඇති ශ්‍රිතයක් ලෙස භාවිතා කළ හැකිය. මේ ආකාරයට, එය නිදසුනක් ලෙස අර්ධ ශ්‍රිතයක් ලෙස ක්‍රියා කරයි:

>>> join_with_colons('abcde')
'a:b:c:d:e'
>>> join_with_colons(['FF', 'FF', 'FF', 'FF', 'FF', 'FF'])
'FF:FF:FF:FF:FF:FF'

ස්ථිතික ක්‍රමය

ස්ථිතික ක්රමය වන්නේ නැහැ තර්කයක් ලෙස උදාහරණයක් ගන්න.

එය මොඩියුල මට්ටමේ ශ්‍රිතයකට බෙහෙවින් සමාන ය.

කෙසේ වෙතත්, මොඩියුල මට්ටමේ ශ්‍රිතයක් මොඩියුලයේ ජීවත් විය යුතු අතර එය භාවිතා කරන වෙනත් ස්ථානවලට විශේෂයෙන් ආනයනය කළ යුතුය.

කෙසේ වෙතත්, එය වස්තුවට අනුයුක්ත කර ඇත්නම්, එය ආනයනය හා උරුමය තුළින් පහසුවෙන් වස්තුව අනුගමනය කරනු ඇත.

ස්ථිතික ක්‍රමයකට උදාහරණයක් පයිතන් 3 හි මොඩියුලයෙන් str.maketransගෙන යනු ලැබේ string. එය පරිභෝජනයට සුදුසු පරිවර්තන වගුවක් කරයි str.translate. පහත දැක්වෙන පරිදි, නූලක උදාහරණයකින් භාවිතා කරන විට එය මෝඩකමක් සේ පෙනේ, නමුත් stringමොඩියුලයෙන් ශ්‍රිතය ආනයනය කිරීම තරමක් අවුල් සහගත වන අතර පන්තියේ සිට එය ඇමතීමට හැකිවීම සතුටක්.str.maketrans

# demonstrate same function whether called from instance or not:
>>> ', '.maketrans('ABC', 'abc')
{65: 97, 66: 98, 67: 99}
>>> str.maketrans('ABC', 'abc')
{65: 97, 66: 98, 67: 99}

පයිතන් 2 හි, වැඩි වැඩියෙන් ප්‍රයෝජනවත් නොවන නූල් මොඩියුලයෙන් ඔබට මෙම ශ්‍රිතය ආනයනය කළ යුතුය:

>>> import string
>>> 'ABCDEFG'.translate(string.maketrans('ABC', 'abc'))
'abcDEFG'

පන්ති ක්‍රමය

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

බිල්ඩින් පංති ක්‍රමයක් සඳහා වඩාත්ම කැනොනිකල් උදාහරණය නම් dict.fromkeys. එය විකල්පයේ ඉදිකිරීම්කරුවෙකු ලෙස භාවිතා කරයි, (ඔබේ යතුරු මොනවාදැයි ඔබ දන්නා විට සහ ඒවා සඳහා පෙරනිමි අගයක් අවශ්‍ය විට එය හොඳින් ගැලපේ.)

>>> dict.fromkeys(['a', 'b', 'c'])
{'c': None, 'b': None, 'a': None}

අපි උප පංතියේ විධානය කරන විට, අපට උප කාණ්ඩයේ නිදසුනක් නිර්මාණය කරන එකම ඉදිකිරීම්කරු භාවිතා කළ හැකිය.

>>> class MyDict(dict): 'A dict subclass, use to demo classmethods'
>>> md = MyDict.fromkeys(['a', 'b', 'c'])
>>> md
{'a': None, 'c': None, 'b': None}
>>> type(md)
<class '__main__.MyDict'>

බලන්න pandas මූල කේතය විකල්ප ඉදිකරන්නන් වෙනත් සමාන උදාහරණ සඳහා, සහ මත ද නිල Python ප්රලේඛනය බලන්න classmethodසහ staticmethod.


43

මම C ++ සමඟ ක්‍රමලේඛන භාෂාව ඉගෙන ගැනීමට පටන් ගත් අතර පසුව ජාවා සහ පසුව පයිතන් ඉගෙන ගත්තෙමි. එබැවින් මෙම ප්‍රශ්නය මටද කරදරයක් විය.

පංති ක්‍රමය: ජාවා සහ සී ++ මෙන් නොව පයිතන්ට ඉදිකිරීම් අධි බර පැටවීමක් නොමැත. මෙය සාක්ෂාත් කර ගැනීම සඳහා ඔබට භාවිතා කළ හැකිය classmethod. පහත උදාහරණයෙන් මෙය පැහැදිලි වේ

ගේ අපට ඇති අපි දැන් සලකා බලමු Personතර්ක දෙකක් ගනී වන පන්තියේ first_nameහා last_nameහා ගැණුම්කරුවන්ගේ නිර්මාණය Person.

class Person(object):

    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name

දැන්, අවශ්‍යතාවය පැමිණෙන්නේ ඔබට තනි නමක් පමණක් භාවිතා කරමින් පන්තියක් සෑදිය යුතු තැනක නම් first_name, ඔබට පයිතන් හි මෙවැනි දෙයක් කළ නොහැක .

ඔබ වස්තුවක් නිර්මාණය කිරීමට උත්සාහ කරන විට මෙය ඔබට දෝෂයක් ලබා දෙනු ඇත (නිදසුනක්).

class Person(object):

    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name

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

කෙසේ වෙතත්, @classmethodපහත සඳහන් පරිදි ඔබට එකම දේ සාක්ෂාත් කරගත හැකිය

class Person(object):

    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name

    @classmethod
    def get_person(cls, first_name):
        return cls(first_name, "")

ස්ථිතික ක්‍රමය: මෙය තරමක් සරල ය, එය නිදසුනකට හෝ පන්තියට බැඳී නැති අතර පන්ති නාමය භාවිතා කර ඔබට එය හැඳින්විය හැකිය.

එබැවින් ඉහත උදාහරණයේ දී ඔබට first_nameඅක්ෂර 20 නොඉක්මවන වලංගු භාවයක් අවශ්‍ය යැයි කියමු , ඔබට මෙය කළ හැකිය.

@staticmethod  
def validate_name(name):
    return len(name) <= 20

ඔබට භාවිතයෙන් ඇමතිය හැකිය class name

Person.validate_name("Gaurang Shah")

2
එය පැරණි තනතුරකි, නමුත් තර්ක එකක් හෝ දෙකක් පිළිගැනීම ඉදිකිරීම්කරු සාක්ෂාත් කර ගැනීම සඳහා වඩාත් පයිතොනික් ක්‍රමයක් වන්නේ පන්ති ක්‍රමය def __init__(self, first_name, last_name="")වෙනුවට භාවිතා කිරීමයි get_person. මෙම අවස්ථාවේ දී ප්‍රති result ලය හරියටම සමාන වේ.
akarilimano

31

මම හිතන්නේ මීට වඩා හොඳ ප්‍රශ්නයක් වන්නේ "ඔබ @ ක්ලැස්මෙතොඩ් එදිරිව at ස්ටැටික්මෙතෝඩ් භාවිතා කරන්නේ කවදාද?"

පන්ති අර්ථ දැක්වීමට සම්බන්ධ පුද්ගලික සාමාජිකයින්ට පහසුවෙන් ප්‍රවේශ වීමට lass ක්ලැස්මෙතෝඩ් ඔබට ඉඩ දෙයි. තනි වස්තූන් කිරීමට මෙය හොඳ ක්‍රමයකි, නැතහොත් නිර්මාණය කරන ලද වස්තූන්ගේ අවස්ථා ගණන පාලනය කරන කර්මාන්තශාලා පන්ති.

aticstaticmethod ආන්තික කාර්ය සාධන වාසි ලබා දෙයි, නමුත් පංතියෙන් පිටත තනිවම කළ හැකි ශ්‍රිතයක් ලෙස සාක්ෂාත් කරගත නොහැකි පංතියක් තුළ ස්ථිතික ක්‍රමවේදයක් use ලදායී ලෙස භාවිතා කිරීම මා තවම දැක නැත.


31

පයිතන් 2.4 හි ode ඩෙකොරේටර්ස් එකතු කරන ලදි ඔබ පයිතන් <2.4 භාවිතා කරන්නේ නම් ඔබට පන්තියේ ක්‍රමය () සහ ස්ථිතික ක්‍රමය () ශ්‍රිතය භාවිතා කළ හැකිය.

නිදසුනක් ලෙස, ඔබට කර්මාන්තශාලා ක්‍රමයක් නිර්මාණය කිරීමට අවශ්‍ය නම් (පන්තියක් ලබා ගන්නා තර්කය මත පදනම්ව වෙනස් ක්‍රියාවට නැංවීමේ අවස්ථාවක් නැවත ලබා දෙන ශ්‍රිතයක්) ඔබට මෙවැනි දෙයක් කළ හැකිය:

class Cluster(object):

    def _is_cluster_for(cls, name):
        """
        see if this class is the cluster with this name
        this is a classmethod
        """ 
        return cls.__name__ == name
    _is_cluster_for = classmethod(_is_cluster_for)

    #static method
    def getCluster(name):
        """
        static factory method, should be in Cluster class
        returns a cluster object for the given name
        """
        for cls in Cluster.__subclasses__():
            if cls._is_cluster_for(name):
                return cls()
    getCluster = staticmethod(getCluster)

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

_is_cluster_forක්‍රමවේදය පංති ක්‍රමයක් බවට පත් කිරීමේ තවත් වාසියක් වන බැවින් උප පංතියකට එය ක්‍රියාත්මක කිරීම වෙනස් කිරීමට තීරණය කළ හැකිය, සමහර විට එය තරමක් සාමාන්‍ය නිසාත්, එක් වර්ගයක පොකුරු හැසිරවිය හැකි නිසාත්, පන්තියේ නම පරීක්ෂා කිරීම පමණක් ප්‍රමාණවත් නොවේ.


28

ස්ථිතික ක්‍රම:

  • ස්වයං තර්කයක් නොමැති සරල කාර්යයන්.
  • පන්ති ලක්ෂණ මත වැඩ කිරීම; උදාහරණ මත නොවේ.
  • පංතිය සහ උදාහරණය යන දෙකින්ම හැඳින්විය හැකිය.
  • ඒවා තැනීම සඳහා බිල්ට් ශ්‍රිතය ස්ථිතික ක්‍රමය () භාවිතා කරයි.

ස්ථිතික ක්‍රමවල ප්‍රතිලාභ:

  • එය පන්තියේ පරාසයේ ශ්‍රිත නාමය ස්ථානගත කරයි
  • එය ශ්‍රිත කේතය එය භාවිතා කරන ස්ථානයට සමීප කරයි
  • එක් එක් ක්‍රමයට විශේෂයෙන් ආනයනය කිරීමට අවශ්‍ය නොවන බැවින් මොඩියුල මට්ටමේ ක්‍රියාකාරිත්වයට එදිරිව ආනයනය කිරීමට වඩාත් පහසුය

    @staticmethod
    def some_static_method(*args, **kwds):
        pass

පන්ති ක්‍රම:

  • පන්ති නාමයක් ලෙස පළමු තර්කය ඇති කාර්යයන්.
  • පංතිය සහ උදාහරණය යන දෙකින්ම හැඳින්විය හැකිය.
  • මේවා නිර්මාණය කර ඇත්තේ පන්තියේ ක්‍රමයෙන් සාදන ලද ශ්‍රිතයෙනි.

     @classmethod
     def some_class_method(cls, *args, **kwds):
         pass

22

@staticmethodක්‍රම විස්තරය ලෙස පෙරනිමි ශ්‍රිතය අක්‍රීය කරන්න. classmethod ඔබේ ශ්‍රිතය පළමු තර්කය ලෙස අයිති පන්තියට යොමු කරන බහාලුම් ඇමතිය හැකි ය.

>>> class C(object):
...  pass
... 
>>> def f():
...  pass
... 
>>> staticmethod(f).__get__(None, C)
<function f at 0x5c1cf0>
>>> classmethod(f).__get__(None, C)
<bound method type.f of <class '__main__.C'>>

ඇත්ත වශයෙන්ම, classmethodධාවන කාලයට ඉහළින් ඇති නමුත් එය අයිති පන්තියට ප්‍රවේශ විය හැකිය. විකල්පයක් ලෙස මම නිර්දේශ කරන්නේ මෙටාක්ලාස් එකක් භාවිතා කර පන්ති ක්‍රම එම මෙටාක්ලාස් මත තැබීම:

>>> class CMeta(type):
...  def foo(cls):
...   print cls
... 
>>> class C(object):
...  __metaclass__ = CMeta
... 
>>> C.foo()
<class '__main__.C'>

1
මෙටාක්ලාස් එකක ඇති විය හැකි අවාසිය නම් මට ක්ෂණිකව සිදුවිය හැකි දෙයක් නම්, ඔබට පන්තියේ ක්‍රමයට සෘජුවම ඇමතිය නොහැකි වීමයි. c = C(); c.foo()AttributeError මතු කරයි, ඔබට කළ යුතුව ඇත type(c).foo(). මෙයද අංගයක් ලෙස සැලකිය හැකිය - ඔබට එසේ වීමට අවශ්‍ය ඇයිදැයි මට සිතා ගත නොහැක.
ආරොන් හෝල්

20

පයිතන්හි ස්ථිතික, පංති හෝ වියුක්ත ක්‍රම භාවිතා කරන්නේ කෙසේද යන්න පිළිබඳ නිශ්චිත මාර්ගෝපදේශය මෙම මාතෘකාව සඳහා එක් හොඳ සබැඳියක් වන අතර එය පහත පරිදි සාරාංශ කරන්න.

@staticmethodශ්‍රිතය යනු පන්තියක් තුළ අර්ථ දක්වා ඇති ශ්‍රිතයකට වඩා වැඩි දෙයක් නොවේ. පළමුව පංතිය ස්ථාපනය නොකර එය ඇමතිය හැකිය. එහි අර්ථ දැක්වීම උරුමය හරහා වෙනස් කළ නොහැකිය.

  • පයිතන්ට වස්තුව සඳහා මායිම් ක්‍රමයක් ක්ෂණිකව දැක්විය යුතු නැත.
  • එය කේතයේ කියවීමේ හැකියාව ලිහිල් කරන අතර එය වස්තුවේ තත්වය මත රඳා නොපවතී;

@classmethodපංතිය ක්ෂණිකව ක්‍රියාත්මක නොකර ශ්‍රිතය ද හැඳින්විය හැකි නමුත් එහි අර්ථ දැක්වීම උප පංතිය අනුගමනය කරයි, මාපිය පන්තිය නොව, උරුමය හරහා, උප පංතිය මගින් අභිබවා යා හැකිය. එයට හේතුව @classmethodශ්‍රිතය සඳහා වන පළමු තර්කය සෑම විටම cls (පන්තිය) විය යුතුය.

  • කර්මාන්තශාලා ක්‍රමපංති සඳහා නිදසුනක් නිර්මාණය කිරීම සඳහා භාවිතා කරන , උදාහරණයක් ලෙස යම් ආකාරයක පෙර සැකසුම් භාවිතා කරයි.
  • ස්ථිතික ක්‍රම කැඳවන ස්ථිතික ක්‍රම : ඔබ ස්ථිතික ක්‍රම කිහිපයක් ස්ථිතික ක්‍රම කිහිපයකට බෙදුවහොත්, ඔබ පන්තියේ නම තදින් කේත නොකළ යුතු අතර පන්ති ක්‍රම භාවිතා කළ යුතුය

ස්තූතියි angzangw - ස්ථිතික ක්‍රියාකාරිත්වයේ උරුම වූ වෙනස්වීම එය පෙනෙන ප්‍රධාන වෙනසයි
hard_working_ant

18

පළමු තර්කය පමණක් වෙනස් වේ :

  • සාමාන්‍ය ක්‍රමය: වත්මන් වස්තුව ස්වයංක්‍රීයව (අතිරේක) පළමු තර්කයක් ලෙස සම්මත වුවහොත්
  • classmethod: වත්මන් වස්තුවේ පන්තිය ස්වයංක්‍රීයව (අතිරේක) හස්ත තර්කයක් ලෙස සම්මත වේ
  • staticmethod: අමතර තර්ක කිසිවක් ස්වයංක්‍රීයව සම්මත නොවේ. ඔබ ශ්‍රිතයට ලබා දුන් දෙය ඔබට ලැබෙන දෙයයි.

වඩාත් විස්තරාත්මකව ...

සාමාන්‍ය ක්‍රමය

වස්තුවක ක්‍රමය හැඳින්වූ විට, එය ස්වයංක්‍රීයව selfඑහි පළමු තර්කය ලෙස අමතර තර්කයක් ලබා දේ . එනම් ක්‍රමයයි

def f(self, x, y)

තර්ක 2 කින් කැඳවිය යුතුය. selfස්වයංක්‍රීයව සම්මත වන අතර එය වස්තුවම වේ .

පන්ති ක්‍රමය

ක්රමය අලංකාර කරන විට

@classmethod
def f(cls, x, y)

ස්වයංක්‍රීයව සපයන තර්කය නොවේ self , නමුත් පන්තිය self .

ස්ථිතික ක්‍රමය

ක්රමය අලංකාර කරන විට

@staticmethod
def f(x, y)

ක්‍රමයට කිසිදු ස්වයංක්‍රීය තර්කයක් ලබා නොදේ . එයට ලබා දී ඇත්තේ එය සමඟ හඳුන්වන පරාමිතීන් පමණි.

භාවිතයන්

  • classmethod විකල්ප ඉදිකිරීම්කරුවන් සඳහා වැඩි වශයෙන් භාවිතා වේ.
  • staticmethodවස්තුවේ තත්වය භාවිතා නොකරයි. එය පන්තියකට බාහිර ශ්‍රිතයක් විය හැකිය. එය සමාන ක්‍රියාකාරීත්වයක් සහිත කාණ්ඩගත කිරීම සඳහා පමණක් පන්තිය තුළට දමනු ලැබේ (නිදසුනක් ලෙස, ජාවාගේ Mathපන්ති ස්ථිතික ක්‍රම වැනි)
class Point
    def __init__(self, x, y):
        self.x = x
        self.y = y

    @classmethod
    def frompolar(cls, radius, angle):
        """The `cls` argument is the `Point` class itself"""
        return cls(radius * cos(angle), radius * sin(angle))

    @staticmethod
    def angle(x, y):
        """this could be outside the class, but we put it here 
just because we think it is logically related to the class."""
        return atan(y, x)


p1 = Point(3, 2)
p2 = Point.frompolar(3, pi/4)

angle = Point.angle(3, 2)

17

මුලින්ම @classmethod vs @staticmethod වලින් සරසා ඇති ක්‍රමයක් අතර ඇති සමානකම මට කියන්නම්.

සමානතාව: ඔවුන් දෙදෙනාම පන්තියේ උදාහරණයට වඩා පන්තියට කැඳවිය හැකිය . ඉතින්, මේ දෙකම අර්ථයෙන් පංතියේ ක්‍රම වේ.

වෙනස: පංති ක්‍රමයක් පළමු තර්කය ලෙස පන්තියම ලබා ගන්නා අතර ස්ථිතික ක්‍රමයක් නොලැබේ.

එබැවින් ස්ථිතික ක්‍රමයක් යනු අර්ථයෙන් ගත් කල, පන්තියටම බැඳී නොසිටින අතර එයට සම්බන්ධ ක්‍රියාකාරීත්වයක් තිබිය හැකි නිසා පමණක් එහි රැඳී සිටියි.

>>> class Klaus:
        @classmethod
        def classmthd(*args):
            return args

        @staticmethod
        def staticmthd(*args):
            return args

# 1. Call classmethod without any arg
>>> Klaus.classmthd()  
(__main__.Klaus,)  # the class gets passed as the first argument

# 2. Call classmethod with 1 arg
>>> Klaus.classmthd('chumma')
(__main__.Klaus, 'chumma')

# 3. Call staticmethod without any arg
>>> Klaus.staticmthd()  
()

# 4. Call staticmethod with 1 arg
>>> Klaus.staticmthd('chumma')
('chumma',)

11

ස්ථිතික ක්‍රමයට එදිරිව පංති ක්‍රමයට සාපේක්ෂව තවත් කරුණක් උරුමය සමඟ පැමිණේ. ඔබට පහත පන්තිය ඇති බව පවසන්න:

class Foo(object):
    @staticmethod
    def bar():
        return "In Foo"

එවිට ඔබට bar()ළමා පන්තියක අභිබවා යාමට අවශ්‍යය :

class Foo2(Foo):
    @staticmethod
    def bar():
        return "In Foo2"

මෙය ක්‍රියාත්මක වන නමුත් දැන් bar()ළමා පන්තියේ ( Foo2) ක්‍රියාත්මක කිරීම තවදුරටත් එම පන්තියට විශේෂිත වූ දෙයකින් ප්‍රයෝජන ගත නොහැකි බව සලකන්න. නිදසුනක් ලෙස, ක්‍රියාත්මක කිරීමේදී ඔබට භාවිතා කිරීමට අවශ්‍ය Foo2ක්‍රමයක් යැයි කියනු ලැබේ :magic()Foo2bar()

class Foo2(Foo):
    @staticmethod
    def bar():
        return "In Foo2"
    @staticmethod
    def magic():
        return "Something useful you'd like to use in bar, but now can't" 

මෙහි සඳහන් ඈඳිය කැඳවීමට වනු Foo2.magic()දී bar(), නමුත්, පසුව, ඔයා තමයි ඔබ නැවත නැවත (නම නම් Foo2වෙනස් කිරීම්, ඔබට යාවත්කාලීන කිරීමට මතක තබා ගැනීමට සිදුවේවි bar()ක්රමය).

මට නම්, මෙය විවෘත / සංවෘත මූලධර්මය සුළු වශයෙන් උල්ලං is නය කිරීමකි , මන්ද ගත් තීරණයක් Fooව්‍යුත්පන්න පන්තියක පොදු කේත ප්‍රතිනිර්මාණය කිරීමේ හැකියාව කෙරෙහි බලපායි (එනම් එය දිගුව සඳහා විවෘතව අඩුය). නම් bar()ලබා සිටි classmethodඅප හොදින් කියලා:

class Foo(object):
    @classmethod
    def bar(cls):
        return "In Foo"

class Foo2(Foo):
    @classmethod
    def bar(cls):
        return "In Foo2 " + cls.magic()
    @classmethod
    def magic(cls):
        return "MAGIC"

print Foo2().bar()

ලබා දෙයි: In Foo2 MAGIC


7

උදාහරණයක් භාවිතා කරමින් මූලික වෙනස පැහැදිලි කිරීමට මම උත්සාහ කරමි.

class A(object):
    x = 0

    def say_hi(self):
        pass

    @staticmethod
    def say_hi_static():
        pass

    @classmethod
    def say_hi_class(cls):
        pass

    def run_self(self):
        self.x += 1
        print self.x # outputs 1
        self.say_hi()
        self.say_hi_static()
        self.say_hi_class()

    @staticmethod
    def run_static():
        print A.x  # outputs 0
        # A.say_hi() #  wrong
        A.say_hi_static()
        A.say_hi_class()

    @classmethod
    def run_class(cls):
        print cls.x # outputs 0
        # cls.say_hi() #  wrong
        cls.say_hi_static()
        cls.say_hi_class()

1 - ආරම්භ කිරීමකින් තොරව අපට ස්ථිතික හා පන්ති ක්‍රම කෙලින්ම ඇමතිය හැකිය

# A.run_self() #  wrong
A.run_static()
A.run_class()

2- ස්ථිතික ක්‍රමයට ස්වයං ක්‍රමයක් ඇමතිය නොහැකි නමුත් වෙනත් ස්ථිතික හා පන්ති ක්‍රම ඇමතිය හැකිය

3- ස්ථිතික ක්‍රමය පන්තියට අයත් වන අතර කිසිසේත් වස්තුව භාවිතා නොකරනු ඇත.

4- පන්ති ක්‍රමය වස්තුවකට නොව පන්තියකට බැඳී ඇත.


දැන්වීම 2: ඔබට විශ්වාසද? ස්ථිතික ක්‍රමය පන්තියේ ක්‍රමය ලෙස හඳුන්වන්නේ කෙසේද? එයට (එහි පන්තියට) කිසිදු සඳහනක් නොමැත.
mirek

7

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

atic ස්ථිතික ක්‍රමය: පංතිය හෝ උදාහරණය සමඟ සම්බන්ධ වීම සමග කිසිදු සම්බන්ධයක් නොමැත ... නමුත් කියවීමේ හැකියාව සඳහා ස්ථිතික ක්‍රමය භාවිතා කළ හැකිය


5

අතර වෙනස සලකා බැලීමට ඔබට අවශ්‍ය විය හැකිය:

Class A:
    def foo():  # no self parameter, no decorator
        pass

හා

Class B:
    @staticmethod
    def foo():  # no self parameter
        pass

මෙය python2 සහ python3 අතර වෙනස් වී ඇත:

python2:

>>> A.foo()
TypeError
>>> A().foo()
TypeError
>>> B.foo()
>>> B().foo()

python3:

>>> A.foo()
>>> A().foo()
TypeError
>>> B.foo()
>>> B().foo()

එබැවින් @staticmethodපංතියෙන් කෙලින්ම කැඳවන ක්‍රම සඳහා භාවිතා කිරීම පයිතන් 3 හි විකල්පයක් වී ඇත. පංතියෙන් සහ උදාහරණ දෙකෙන්ම ඔබට ඔවුන් ඇමතීමට අවශ්‍ය නම්, ඔබ තවමත් @staticmethodසැරසිලි කරුවා භාවිතා කළ යුතුය.

අනෙක් සිද්ධීන් අනවශ්‍ය පිළිතුරු මගින් හොඳින් ආවරණය වී ඇත.


5

පංති ක්‍රමයක් මඟින් පංතිය ව්‍යංග පළමු තර්කය ලෙස ලබා ගනී. එය පංතියට බැඳී ඇති ක්‍රමයක් වන අතර එය පන්තියේ වස්තුව නොවේ. පන්තියේ තත්වයට ප්‍රවේශය ඇත්තේ පන්තියට පරාමිතියක් ගන්නා අතර එය වස්තු උදාහරණය නොවේ. පංතියේ සෑම අවස්ථාවකම අදාළ වන පන්ති තත්වයක් එයට වෙනස් කළ හැකිය. උදාහරණයක් ලෙස එය සියලු අවස්ථාවන්ට අදාළ වන පන්ති විචල්‍යයක් වෙනස් කළ හැකිය.

අනෙක් අතට, පන්ති ක්‍රම හෝ නිදර්ශන ක්‍රම සමඟ සසඳන විට ස්ථිතික ක්‍රමයකට ව්‍යාජ පළමු තර්කයක් නොලැබේ. පන්ති තත්වයට ප්‍රවේශ වීමට හෝ වෙනස් කිරීමට නොහැක. එය පන්තියට අයත් වන්නේ නිර්මාණ දෘෂ්ටි කෝණයෙන් එය නිවැරදි ක්‍රමය වන බැවිනි. නමුත් ක්‍රියාකාරීත්වය අනුව, ධාවන වේලාවේදී පන්තියට බැඳී නොමැත.

මාර්ගෝපදේශයක් ලෙස, ස්ථිතික ක්‍රම උපයෝගීතා ලෙස භාවිතා කරන්න, පන්ති ක්‍රම උදාහරණයක් ලෙස කර්මාන්තශාලා ලෙස භාවිතා කරන්න. නැතිනම් සිංගල්ටන් එකක් අර්ථ දැක්වීමට විය හැකිය. සිද්ධි වල තත්වය සහ හැසිරීම ආදර්ශනය කිරීමට නිදර්ශන ක්‍රම භාවිතා කරන්න.

මම පැහැදිලි යැයි සිතමි!


4

මගේ දායකත්වය අතර වෙනස පෙන්නුම් @classmethod, @staticmethodහා උදාහරණයක් ක්රම, නිදසුනක් වන වක්රව ඇමතිය හැකි ආකාරය ඇතුළු @staticmethod. නමුත් @staticmethodඋදාහරණයකින් වක්‍රව ඇමතීම වෙනුවට එය පුද්ගලික කිරීම වඩාත් “පයිතොනික්” විය හැකිය. පුද්ගලික ක්‍රමයකින් යමක් ලබා ගැනීම මෙහි නිරූපණය නොකෙරේ, නමුත් එය මූලික වශයෙන් එකම සංකල්පයකි.

#!python3

from os import system
system('cls')
# %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %

class DemoClass(object):
    # instance methods need a class instance and
    # can access the instance through 'self'
    def instance_method_1(self):
        return 'called from inside the instance_method_1()'

    def instance_method_2(self):
        # an instance outside the class indirectly calls the static_method
        return self.static_method() + ' via instance_method_2()'

    # class methods don't need a class instance, they can't access the
    # instance (self) but they have access to the class itself via 'cls'
    @classmethod
    def class_method(cls):
        return 'called from inside the class_method()'

    # static methods don't have access to 'cls' or 'self', they work like
    # regular functions but belong to the class' namespace
    @staticmethod
    def static_method():
        return 'called from inside the static_method()'
# %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %

# works even if the class hasn't been instantiated
print(DemoClass.class_method() + '\n')
''' called from inside the class_method() '''

# works even if the class hasn't been instantiated
print(DemoClass.static_method() + '\n')
''' called from inside the static_method() '''
# %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %   %

# >>>>> all methods types can be called on a class instance <<<<<
# instantiate the class
democlassObj = DemoClass()

# call instance_method_1()
print(democlassObj.instance_method_1() + '\n')
''' called from inside the instance_method_1() '''

# # indirectly call static_method through instance_method_2(), there's really no use
# for this since a @staticmethod can be called whether the class has been
# instantiated or not
print(democlassObj.instance_method_2() + '\n')
''' called from inside the static_method() via instance_method_2() '''

# call class_method()
print(democlassObj.class_method() + '\n')
'''  called from inside the class_method() '''

# call static_method()
print(democlassObj.static_method())
''' called from inside the static_method() '''

"""
# whether the class is instantiated or not, this doesn't work
print(DemoClass.instance_method_1() + '\n')
'''
TypeError: TypeError: unbound method instancemethod() must be called with
DemoClass instance as first argument (got nothing instead)
'''
"""

2

පංති ක්‍රම, නමට අනුව, වස්තූන් නොව පන්තිවල වෙනස්කම් කිරීමට යොදා ගනී. පංතිවල වෙනස්කම් සිදු කිරීම සඳහා, ඔවුන් පන්ති ගුණාංග වෙනස් කරනු ඇත (වස්තු ගුණාංග නොවේ), මන්ද ඔබ පන්ති යාවත්කාලීන කරන්නේ එලෙසිනි. පංති ක්‍රම මගින් පළමු තර්කය ලෙස පන්තිය (සාම්ප්‍රදායිකව 'cls' ලෙස දක්වනු ලැබේ).

class A(object):
    m=54

    @classmethod
    def class_method(cls):
        print "m is %d" % cls.m

අනෙක් අතට ස්ථිතික ක්‍රම භාවිතා කරනුයේ පන්තියට බැඳී නැති ක්‍රියාකාරීත්වයන් සිදු කිරීමට ය, එනම් ඒවා පන්ති විචල්‍යයන් කියවීමට හෝ ලිවීමට නොහැකි වනු ඇත. එබැවින් ස්ථිතික ක්‍රම මගින් පන්ති තර්ක ලෙස නොගනී. පංතියේ අරමුණට directly ජුව සම්බන්ධ නොවන ක්‍රියාකාරීත්වයන් පන්තිවලට ඉටු කිරීමට හැකි වන පරිදි ඒවා භාවිතා කරනු ලැබේ.

class X(object):
    m=54 #will not be referenced

    @staticmethod
    def static_method():
        print "Referencing/calling a variable or function outside this class. E.g. Some global variable/function."

2

Atic ස්ථිතික ක්‍රමවේදය වචනාර්ථයෙන් විශ්ලේෂණය කරන්න වෙනස් අවබෝධයක් ලබා දීම .

පංතියක සාමාන්‍ය ක්‍රමයක් යනු ව්‍යංග ගතික ක්‍රමයක් වන අතර එය උදාහරණය පළමු තර්කය ලෙස ගනී.
ඊට හාත්පසින්ම වෙනස්ව, ස්ථිතික ක්‍රමයක් උදාහරණය පළමු තර්කය ලෙස නොසලකයි, එබැවින් එය 'ස්ථිතික' ලෙස හැඳින්වේ .

ස්ථිතික ක්‍රමයක් යනු පන්ති අර්ථ දැක්වීමකට පිටතින් සිදු වන සාමාන්‍ය ක්‍රියාවකි.
එය වාසනාවකට පංතියට ඇතුළත් කර ඇත්තේ එය යොදන ස්ථානයට සමීපව සිටීම සඳහා ය, නැතහොත් ඔබට එය සොයා ගැනීමට අනුචලනය කළ හැකිය.


2

මම හිතන්නේ තනිකරම පයිතන් අනුවාදයක් staticmethodසහclassmethod භාෂා මට්ටමින් ඒවා අතර වෙනස තේරුම් ගැනීමට උපකාරී වනු ඇත.

ඔවුන් දෙදෙනාම දත්ත නොවන විස්තර කරන්නන් වේ (ඔබ මුලින් විස්තර කරන්නන් සමඟ හුරුපුරුදු නම් ඒවා තේරුම් ගැනීම පහසු වනු ඇත ).

class StaticMethod(object):
    "Emulate PyStaticMethod_Type() in Objects/funcobject.c"

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

    def __get__(self, obj, objtype=None):
        return self.f


class ClassMethod(object):
    "Emulate PyClassMethod_Type() in Objects/funcobject.c"
    def __init__(self, f):
        self.f = f

    def __get__(self, obj, cls=None):
        def inner(*args, **kwargs):
            if cls is None:
                cls = type(obj)
            return self.f(cls, *args, **kwargs)
        return inner

1

ස්ථිතික ක්‍රමයට උරුමය ධූරාවලිය තුළ වස්තුව, පන්තිය හෝ මව් පංතිවල ආකල්ප වලට ප්‍රවේශයක් නොමැත. එය කෙලින්ම පන්තියට කැඳවිය හැකිය (වස්තුවක් නිර්මාණය නොකර).

classmethod හට වස්තුවේ ගුණාංග වෙත ප්‍රවේශයක් නොමැත. කෙසේ වෙතත්, උරුමය ධූරාවලිය තුළ පන්තියේ සහ මව් පංතිවල ලක්ෂණ වලට ප්‍රවේශ විය හැකිය. එය කෙලින්ම පන්තියට කැඳවිය හැකිය (වස්තුවක් නිර්මාණය නොකර). වස්තුවට ඇමතුමක් ලබා දෙන්නේ නම් එය ප්‍රවේශ නොවන self.<attribute(s)>හා ප්‍රවේශ නොවන සාමාන්‍ය ක්‍රමයට සමාන වේself.__class__.<attribute(s)> .

අපට පංතියක් ඇතැයි සිතන්න b=2, අපි වස්තුවක් නිර්මාණය කර එය නැවත එය තුළට සකසමු b=4. ස්ථිතික ක්‍රමයට පෙර සිට කිසිවක් ප්‍රවේශ කළ නොහැක. පංති ක්‍රමයට ප්‍රවේශ විය .b==2හැක්කේ, හරහා පමණි cls.b. සාමාන්‍ය ක්‍රමයට ප්‍රවේශ විය හැකිය: .b==4හරහා self.bසහ .b==2හරහා self.__class__.b.

අපට KISS ශෛලිය අනුගමනය කළ හැකිය (එය සරල, මෝඩ ලෙස තබා ගන්න): ස්ථිතික ක්‍රම සහ පන්ති ක්‍රම භාවිතා නොකරන්න, ඒවා ක්ෂණිකව භාවිතා නොකර පන්ති භාවිතා නොකරන්න, වස්තුවේ ලක්ෂණ වලට පමණක් ප්‍රවේශ වන්න self.attribute(s). OOP ඒ ආකාරයෙන් ක්‍රියාත්මක කරන භාෂා ඇති අතර එය නරක අදහසක් නොවන බව මම සිතමි. :)


පංති ක්‍රම සඳහා තවත් වැදගත් දෙයක්: ඔබ පන්ති ක්‍රමයේ ගුණාංගයක් වෙනස් කරන්නේ නම්, මෙම ගුණාංගය පැහැදිලිව සකසා නැති මෙම පන්තියේ දැනට පවතින සියලුම වස්තූන් නවීකරණය කරන ලද අගයක් ඇත.
mirek

-4

අයිපයිතන් හි ඉක්මණින් අනවසරයෙන් සමාන ක්‍රම මගින් හෙළි වන්නේ @staticmethodආන්තික කාර්ය සාධනය (නැනෝ තත්පර වලින්) ලබා දෙන බවයි, නමුත් වෙනත් ආකාරයකින් එය කිසිදු කාර්යයක් ඉටු නොකරන බව පෙනේ. එසේම, staticmethod()සම්පාදනය අතරතුරදී ක්‍රමවේදය සැකසීමේ අතිරේක කාර්යයන් මඟින් ඕනෑම කාර්ය සාධන ලාභයක් අතුගා දමනු ඇත (ඔබ ස්ක්‍රිප්ට් එකක් ධාවනය කරන විට ඕනෑම කේත ක්‍රියාත්මක කිරීමට පෙර සිදු වේ).

කේත කියවීමේ හැකියාව @staticmethodසඳහා, නැනෝ තත්පර ගණන් කරන වැඩ ගොඩක් සඳහා ඔබේ ක්‍රමය භාවිතා නොකරන්නේ නම් මම වැළකී සිටිමි .


7
"එසේ නොමැතිනම් කිසිදු කාර්යයක් ඉටු නොවන බව පෙනේ": තදින් සත්‍ය නොවේ. ඉහත සාකච්ඡාව බලන්න.
කීත් පින්සන්
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.