පයිතන්හි ස්ථිතික පන්ති විචල්‍යයන් පැවතිය හැකිද?


1961

පයිතන්හි ස්ථිතික පන්ති විචල්‍යයන් හෝ ක්‍රම තිබිය හැකිද? මෙය සිදු කිරීම සඳහා අවශ්‍ය වන වාක්‍ය ඛණ්ඩය කුමක්ද?

Answers:


1913

පන්ති අර්ථ දැක්වීම තුළ ප්‍රකාශිත විචල්‍යයන්, නමුත් ක්‍රමයක් තුළ නොව පන්ති හෝ ස්ථිතික විචල්‍යයන් වේ:

>>> class MyClass:
...     i = 3
...
>>> MyClass.i
3 

@ මිලර්දේව් පෙන්වා දෙන පරිදි, මෙය පන්ති මට්ටමේ iවිචල්‍යයක් නිර්මාණය කරයි , නමුත් මෙය ඕනෑම නිදර්ශන මට්ටමේ iවිචල්‍යයකට වඩා වෙනස් වේ, එබැවින් ඔබට තිබිය හැකිය

>>> m = MyClass()
>>> m.i = 4
>>> MyClass.i, m.i
>>> (3, 4)

මෙය C ++ සහ Java වලට වඩා වෙනස් නමුත් C # ට වඩා වෙනස් නොවේ, එහිදී ස්ථිතික සාමාජිකයෙකුට නිදසුනක් වෙත යොමු කිරීමක් භාවිතා කළ නොහැක.

පංති සහ පන්ති වස්තු පිළිබඳ පයිතන් නිබන්ධනයට කුමක් කිව හැකිදැයි බලන්න .

Ste ස්ටීව් ජොන්සන් ස්ථිතික ක්‍රම පිළිබඳව දැනටමත් පිළිතුරු ලබා දී ඇති අතර, පයිතන් පුස්තකාල විමර්ශනයේ “බිල්ට් ඉන් ෆන්ෂන්ස් යටතේ ලේඛනගත කර ඇත.

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

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


12
මම දැන් පයිතන් ඉගෙන ගන්නවා, නමුත් AFAIK @classmethodට වඩා වැඩි වාසි @staticmethodවන්නේ ඔබ සෑම විටම පන්තියේ නම ලබා ගැනීමයි. එය උප පංතියක් වුවද. ස්ථිතික ක්‍රමයකට මෙම තොරතුරු නොමැති බැවින් එයට අභිබවා ගිය ක්‍රමයක් ඇමතිය නොහැක.
සෙබ්

49
JtheJollySin නියතයන් සඳහා පයිතොනික් ක්‍රමය නම් නියතයන් සඳහා පන්තියක් වර්ධනය නොකිරීමයි. සමහරක් const.pyඇති PI = 3.14අතර ඔබට එය සෑම තැනකම ආනයනය කළ හැකිය. from const import PI
ගිස්මෝ

31
මෙම පිළිතුර ස්ථිතික විචල්‍ය ගැටළුව ව්‍යාකූල කිරීමට ඉඩ ඇත. ආරම්භ කිරීම සඳහා, i = 3වන නොවේ ස්ථිතික විචල්ය, එය පන්ති ලක්ෂණයට, සහ එය නිදසුනක් මට්ටමේ ලක්ෂණයට වඩා වෙනස් වේ සිට iඑය කරන්නේ නැහැ අනෙක් භාෂාවල ස්ථිතික විචල්ය වගේ හැසිරෙන්න. බලන්න millerdev පිළිතුර , Yann පිළිතුර , සහ මගේ පිළිතුර පහත.
රික් මොනිකා

2
iමම මෙම පන්තියේ අවස්ථා සිය ගණනක් නිර්මාණය කළත් (ස්ථිතික විචල්‍යයේ) එක් පිටපතක් පමණක් මතකයේ පවතින්නේද?
sdream

2
ඩබ්ස්ලෝ අදහස් දැක්වීමේදී ඩැනියෙල් ගැන උනන්දුවක් දක්වන ඕනෑම අයෙකුට එය මිලර්දේව් ( වේබැක් යන්ත්‍රය )
හේයිජුඩ්

621

La බ්ලෙයාර් කොන්රාඩ් පැවසුවේ පන්ති අර්ථ දැක්වීම තුළ ස්ථිතික විචල්‍යයන් ප්‍රකාශයට පත් කර ඇති නමුත් ක්‍රමයක් තුළ නොව පන්ති හෝ ස්ථිතික විචල්‍යයන්:

>>> class Test(object):
...     i = 3
...
>>> Test.i
3

ගොචා කිහිපයක් මෙහි ඇත. ඉහත උදාහරණයෙන් ඉදිරියට යාම:

>>> t = Test()
>>> t.i     # "static" variable accessed via instance
3
>>> t.i = 5 # but if we assign to the instance ...
>>> Test.i  # we have not changed the "static" variable
3
>>> t.i     # we have overwritten Test.i on t by creating a new attribute t.i
5
>>> Test.i = 6 # to change the "static" variable we do it by assigning to the class
>>> t.i
5
>>> Test.i
6
>>> u = Test()
>>> u.i
6           # changes to t do not affect new instances of Test

# Namespaces are one honking great idea -- let's do more of those!
>>> Test.__dict__
{'i': 6, ...}
>>> t.__dict__
{'i': 5}
>>> u.__dict__
{}

t.iආරෝපණය iකෙලින්ම සකසා ඇති විට නිදර්ශන විචල්‍යය “ස්ථිතික” පන්ති විචල්‍යය සමඟ සමමුහුර්ත වී ඇති ආකාරය සැලකිල්ලට ගන්න t. මෙයට හේතුව නාම අවකාශය iතුළ නැවත බැඳී තිබීමයි t, එය නාම අවකාශයට වඩා වෙනස් ය Test. ඔබට "ස්ථිතික" විචල්‍යයක අගය වෙනස් කිරීමට අවශ්‍ය නම්, එය මුලින් අර්ථ දක්වා ඇති විෂය පථය තුළ (හෝ වස්තුව) වෙනස් කළ යුතුය. C ++ සහ Java යන අර්ථයෙන් පයිතන්ට ස්ථිතික විචල්‍යයන් නොමැති නිසා මම "ස්ථිතික" උපුටා දැක්වීම් වලට දැමුවෙමි.

ස්ථිතික විචල්‍යයන් හෝ ක්‍රම පිළිබඳව නිශ්චිත කිසිවක් නොකියුවත්, පයිතන් නිබන්ධනයේ පන්ති සහ පන්ති වස්තු පිළිබඳ අදාළ තොරතුරු තිබේ .

Ste ස්ටීව් ජොන්සන් ස්ථිතික ක්‍රම පිළිබඳව ද පිළිතුරු දුන් අතර, පයිතන් පුස්තකාල විමර්ශනයේ “බිල්ට් ඉන් ෆන්ෂන්ස්” යටතේ ලේඛනගත කර ඇත.

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

id බීඩ් විසින් ස්ථිතික ක්‍රමයට සමාන පංති ක්‍රමයක් ද සඳහන් කර ඇත. පංතියේ ක්‍රමයේ පළමු තර්කය පන්ති වස්තුවයි. උදාහරණයක්:

class Test(object):
    i = 3 # class (or static) variable
    @classmethod
    def g(cls, arg):
        # here we can use 'cls' instead of the class name (Test)
        if arg > cls.i:
            cls.i = arg # would be the same as Test.i = arg1

ඉහත උදාහරණයේ රූපමය නිරූපණය


3
උදාහරණය මඳක් දිගු කිරීමට මම ඔබට යෝජනා කරමි: Test.i = 6 සැකසීමෙන් පසු, ඔබ නව වස්තුවක් (උදා: u = ටෙස්ට් ()) ක්ෂණිකව කළහොත්, නව වස්තුව නව පන්ති අගය "උරුම" කරනු ඇත (උදා. UI == 6)
මාර්ක්

2
සමමුහුර්ත දී සථිර විචල්යයන් තබා ගැනීමට මාර්ගයක් ඔවුන් ගුණ බවට පත් කිරීම: class Test(object):, _i = 3, @property, def i(self), return type(self)._i, @i.setter, def i(self,val):, type(self)._i = val. දැන් ඔබට කළ හැකි x = Test(), x.i = 12, assert x.i == Test.i.
රික් මොනිකාට සහාය දක්වයි

1
ඉතින් මට කියන්න පුළුවන් සියලුම විචල්‍යයන් මුලින් ස්ථිතිකයි, පසුව නිදසුන් වෙත ප්‍රවේශ වීම ධාවන වේලාවේදී නිදසුන් විචල්‍යයන් කරයිද?
අලි

සමහර විට මෙය සිත්ගන්නා සුළුය: ඔබ Test.i වෙනස් කරන ටෙස්ට් ක්‍රමයක් නිර්වචනය කරන්නේ නම්, එය Test.i සහ ti අගයන් දෙකටම බලපායි.
පැබ්ලෝ

@ මිලර්දේව්, ඔබ සඳහන් කළ පරිදි පයිතන්ට C ++ හෝ JAVA මෙන් ස්ථිතික විචල්‍යයන් නොමැත..ඉතින් පැවසීම හරිද, Test.i යනු ස්ථිතික විචල්‍යයකට වඩා පන්ති විචල්‍යයකට වඩා වැඩි ද?
ටයිටෝ

199

ස්ථිතික හා පන්ති ක්‍රම

අනෙක් පිළිතුරු සටහන් කර ඇති පරිදි, ගොඩනඟන ලද සැරසිලි කරුවන් භාවිතා කරමින් ස්ථිතික හා පන්ති ක්‍රම පහසුවෙන් ඉටු කර ගත හැකිය:

class Test(object):

    # regular instance method:
    def MyMethod(self):
        pass

    # class method:
    @classmethod
    def MyClassMethod(klass):
        pass

    # static method:
    @staticmethod
    def MyStaticMethod():
        pass

සුපුරුදු පරිදි, පළමු තර්කය MyMethod()පන්ති නිදර්ශන වස්තුවට බැඳී ඇත. ඊට වෙනස්ව, පළමු තර්කය MyClassMethod()වන්නේ , පන්ති වස්තුව තමන් වෙත බැඳී (උදා: මේ අවස්ථාවේ දී, Test). මක්නිසාද යත් MyStaticMethod(), තර්ක කිසිවක් බැඳී නැති අතර, තර්ක තිබීම කිසිසේත්ම අත්‍යවශ්‍ය නොවේ.

"ස්ථිතික විචල්යයන්"

කෙසේ වෙතත්, "ස්ථිතික විචල්යයන්" ක්රියාත්මක කිරීම (හොඳයි, විකෘති ස්ථිතික විචල්යයන්, කෙසේ වෙතත්, එය ප්රතිවිරෝධයක් නොවේ නම් ...) එතරම් forward ජු ඉදිරියට නොවේ. මිලර්දේව් ඔහුගේ පිළිතුරෙන් පෙන්වා දුන් පරිදි , ගැටළුව වන්නේ පයිතන්ගේ පන්ති ගුණාංග සැබවින්ම “ස්ථිතික විචල්‍යයන්” නොවීමයි. සලකා බලන්න:

class Test(object):
    i = 3  # This is a class attribute

x = Test()
x.i = 12   # Attempt to change the value of the class attribute using x instance
assert x.i == Test.i  # ERROR
assert Test.i == 3    # Test.i was not affected
assert x.i == 12      # x.i is a different object than Test.i

මෙයට හේතුව පන්තියේ ගුණාංගයේ අගය වෙනස් කිරීම වෙනුවට පේළිය x.i = 12නව නිදර්ශන ලක්ෂණයක් එකතු කර ඇති බැවිනි .ixTesti

අර්ධ අපේක්ෂිත ස්ථිතික විචල්ය හැසිරීම, එනම්, බහු අවස්ථා අතර නාලවල සමමුහුර්ත (නමුත් නොවේ පන්ති ම සමග, අඩු "gotcha" බලන්න), දේපළ ද පන්ති විශේෂණය හරවා සාක්ෂාත් කර ගත හැක:

class Test(object):

    _i = 3

    @property
    def i(self):
        return type(self)._i

    @i.setter
    def i(self,val):
        type(self)._i = val

## ALTERNATIVE IMPLEMENTATION - FUNCTIONALLY EQUIVALENT TO ABOVE ##
## (except with separate methods for getting and setting i) ##

class Test(object):

    _i = 3

    def get_i(self):
        return type(self)._i

    def set_i(self,val):
        type(self)._i = val

    i = property(get_i, set_i)

දැන් ඔබට කළ හැකිය:

x1 = Test()
x2 = Test()
x1.i = 50
assert x2.i == x1.i  # no error
assert x2.i == 50    # the property is synced

ස්ථිතික විචල්‍යය දැන් සියලුම පන්ති අවස්ථා අතර සමපාත වේ .

(සටහන: පන්ති උදාහරණයක් තමන්ගේ ම අනුවාදය නිර්වචනය කිරීමට තීරණය නම් එනම්, _i! නැහැ කෙනෙකු ඒක කරන්න තීරණය, තමන් ලබා දේ ලැබිය නම්, ඔවුන් ???)

තාක්‍ෂණිකව කිවහොත් iඑය තවමත් 'ස්ථිතික විචල්‍යයක්' නොවන බව සලකන්න . එය propertyවිශේෂ වර්ගයේ විස්තරයකි. කෙසේ වෙතත්, propertyහැසිරීම දැන් සියලු පන්ති අවස්ථා හරහා සමමුහුර්ත (විකෘති) ස්ථිතික විචල්‍යයකට සමාන වේ.

වෙනස් කළ නොහැකි "ස්ථිතික විචල්යයන්"

වෙනස් කළ නොහැකි ස්ථිතික විචල්‍ය හැසිරීම් සඳහා, සැකසුම propertyමඟහරින්න:

class Test(object):

    _i = 3

    @property
    def i(self):
        return type(self)._i

## ALTERNATIVE IMPLEMENTATION - FUNCTIONALLY EQUIVALENT TO ABOVE ##
## (except with separate methods for getting i) ##

class Test(object):

    _i = 3

    def get_i(self):
        return type(self)._i

    i = property(get_i)

දැන් නිදර්ශන iගුණාංගය සැකසීමට උත්සාහ කිරීමෙන් නැවත ලැබෙනු ඇත AttributeError:

x = Test()
assert x.i == 3  # success
x.i = 12         # ERROR

දැනුවත් විය යුතු එක් ගොචා

සටහන ඉහත ක්රම සමග පමණක් කටයුතු කරන අවස්ථා ඔබගේ පන්තියේ - ඔවුන් ඇත නොහැකි වැඩ පන්ති ම භාවිතා කරන විට . උදාහරණයක් ලෙස:

x = Test()
assert x.i == Test.i  # ERROR

# x.i and Test.i are two different objects:
type(Test.i)  # class 'property'
type(x.i)     # class 'int'

රේඛාව assert Test.i == x.iබැවින්, දෝෂයක් නිෂ්පාදනය iවන 'විශේෂණය Testහා xදෙක වෙනස් ආකාරයකටයි.

බොහෝ අය මෙය පුදුමයට පත් කරනු ඇත. කෙසේ වෙතත්, එය එසේ නොවිය යුතුය. අපි ආපසු ගොස් අපගේ Testපන්ති අර්ථ දැක්වීම (දෙවන අනුවාදය) පරීක්ෂා කරන්නේ නම් , අපි මෙම රේඛාව සැලකිල්ලට ගනිමු:

    i = property(get_i) 

පැහැදිලිවම, සාමාජික iTestතිබිය යුතු වන propertyමෙම සිට ආපසු වස්තුව වර්ගය වන වස්තුවක්, propertyශ්රිතය.

ඉහත ව්‍යාකූල බව ඔබ දුටුවහොත්, ඔබ බොහෝ විට වෙනත් භාෂාවල දෘෂ්ටි කෝණයෙන් ඒ ගැන සිතමින් සිටී (උදා: ජාවා හෝ සී ++). propertyපයිතන් ගුණාංග නැවත ලබා දෙන අනුපිළිවෙල, විස්තර කිරීමේ ප්‍රොටෝකෝලය සහ ක්‍රම විභේදන අනුපිළිවෙල (MRO) ගැන ඔබ වස්තුව අධ්‍යයනය කළ යුතුය .

ඉහත 'ගොචා' සඳහා මම පහත විසඳුමක් ඉදිරිපත් කරමි; කෙසේ වෙතත්, මම යෝජනා කරන්නේ - දැඩි ලෙස - ඔබ පහත සඳහන් දේ වැනි දෙයක් කිරීමට උත්සාහ නොකරන ලෙස - අවම වශයෙන් - assert Test.i = x.iදෝෂයක් ඇතිවීමට හේතුව ඔබ හොඳින් වටහාගෙන ඇත.

සැබෑ, සැබෑ ස්ථිතික විචල්‍යයන් -Test.i == x.i

මම පහත (පයිතන් 3) විසඳුම ඉදිරිපත් කරන්නේ තොරතුරු දැනගැනීම සඳහා පමණි. මම එය "හොඳ විසඳුමක්" ලෙස අනුමත නොකරමි. පයිතන් හි වෙනත් භාෂාවල ස්ථිතික විචල්‍ය හැසිරීම අනුකරණය කිරීම ඇත්ත වශයෙන්ම අවශ්‍යද යන්න පිළිබඳව මට සැකයක් ඇත. කෙසේ වෙතත්, එය සැබවින්ම ප්‍රයෝජනවත්ද යන්න නොසලකා, පයිතන් ක්‍රියා කරන ආකාරය පිළිබඳ වැඩිදුර අවබෝධ කර ගැනීමට පහත දැක්වේ.

යාවත්කාලීන කිරීම: මෙම උත්සාහය ඇත්තෙන්ම භයානක ය ; ඔබ මේ වගේ දෙයක් කිරීමට බල කරන්නේ නම් (ඉඟිය: කරුණාකරලා එපා; පයිතන් ඉතා අලංකාර භාෂාවක් වන අතර වෙනත් භාෂාවක් ලෙස හැසිරීමට එය සපත්තුව දැමීම අවශ්‍ය නොවේ), ඒ වෙනුවට ඊතන් ෆුරමන්ගේ පිළිතුරේ කේතය භාවිතා කරන්න.

මෙටාක්ලාස් භාවිතා කරමින් වෙනත් භාෂාවල ස්ථිතික විචල්‍ය හැසිරීම අනුකරණය කිරීම

මෙටාක්ලාස් යනු පන්තියක පන්තියයි. පයිතන් හි සියලුම පන්ති සඳහා පෙරනිමි මෙටැක්ලාස් (එනම්, "නව විලාසිතාවේ" පන්ති පයිතන් 2.3 පශ්චාත් මම විශ්වාස කරමි) type. උදාහරණයක් වශයෙන්:

type(int)  # class 'type'
type(str)  # class 'type'
class Test(): pass
type(Test) # class 'type'

කෙසේ වෙතත්, ඔබට මේ ආකාරයට ඔබේම මෙටැක්ලාස් අර්ථ දැක්විය හැකිය:

class MyMeta(type): pass

ඔබේ පන්තියට මේ ආකාරයට යොදන්න (පයිතන් 3 පමණි):

class MyClass(metaclass = MyMeta):
    pass

type(MyClass)  # class MyMeta

පහත දැක්වෙන්නේ මා විසින් නිර්මාණය කරන ලද මෙටාක්ලාස් එකක් වන අතර එය වෙනත් භාෂාවල “ස්ථිතික විචල්‍ය” හැසිරීම අනුකරණය කිරීමට උත්සාහ කරයි. එය මූලික වශයෙන් ක්‍රියාත්මක වන්නේ පෙරනිමි ගෙටරය, සැකසුම සහ මකාදැමීම අනුවාදයන් මගින් ප්‍රතිස්ථාපනය කිරීමෙනි.

"ස්ථිතික විචල්යයන්" පිළිබඳ නාමාවලියක් StaticVarMeta.staticsගුණාංගයේ ගබඩා කර ඇත . සියලු ආරෝපණ ඉල්ලීම් මුලින් ආදේශක විසර්ජන නියෝගයක් භාවිතයෙන් විසඳීමට උත්සාහ කරයි. මම මෙය "ස්ථිතික විභේදන අනුපිළිවෙල" හෝ "SRO" ලෙස නම් කර ඇත. මෙය සිදු කරනුයේ දී ඇති පන්තියක් සඳහා (හෝ එහි මව් පංති) “ස්ථිතික විචල්‍යයන්” කට්ටලයේ ඉල්ලූ ගුණාංගය සෙවීමෙනි. "SRO" හි ගුණාංගය නොපෙන්වන්නේ නම්, පන්තිය පෙරනිමි ගුණාංගය ලබා ගනී / සැකසීම / මකා දැමීමේ හැසිරීම (එනම් "MRO") මතට වැටෙනු ඇත.

from functools import wraps

class StaticVarsMeta(type):
    '''A metaclass for creating classes that emulate the "static variable" behavior
    of other languages. I do not advise actually using this for anything!!!

    Behavior is intended to be similar to classes that use __slots__. However, "normal"
    attributes and __statics___ can coexist (unlike with __slots__). 

    Example usage: 

        class MyBaseClass(metaclass = StaticVarsMeta):
            __statics__ = {'a','b','c'}
            i = 0  # regular attribute
            a = 1  # static var defined (optional)

        class MyParentClass(MyBaseClass):
            __statics__ = {'d','e','f'}
            j = 2              # regular attribute
            d, e, f = 3, 4, 5  # Static vars
            a, b, c = 6, 7, 8  # Static vars (inherited from MyBaseClass, defined/re-defined here)

        class MyChildClass(MyParentClass):
            __statics__ = {'a','b','c'}
            j = 2  # regular attribute (redefines j from MyParentClass)
            d, e, f = 9, 10, 11   # Static vars (inherited from MyParentClass, redefined here)
            a, b, c = 12, 13, 14  # Static vars (overriding previous definition in MyParentClass here)'''
    statics = {}
    def __new__(mcls, name, bases, namespace):
        # Get the class object
        cls = super().__new__(mcls, name, bases, namespace)
        # Establish the "statics resolution order"
        cls.__sro__ = tuple(c for c in cls.__mro__ if isinstance(c,mcls))

        # Replace class getter, setter, and deleter for instance attributes
        cls.__getattribute__ = StaticVarsMeta.__inst_getattribute__(cls, cls.__getattribute__)
        cls.__setattr__ = StaticVarsMeta.__inst_setattr__(cls, cls.__setattr__)
        cls.__delattr__ = StaticVarsMeta.__inst_delattr__(cls, cls.__delattr__)
        # Store the list of static variables for the class object
        # This list is permanent and cannot be changed, similar to __slots__
        try:
            mcls.statics[cls] = getattr(cls,'__statics__')
        except AttributeError:
            mcls.statics[cls] = namespace['__statics__'] = set() # No static vars provided
        # Check and make sure the statics var names are strings
        if any(not isinstance(static,str) for static in mcls.statics[cls]):
            typ = dict(zip((not isinstance(static,str) for static in mcls.statics[cls]), map(type,mcls.statics[cls])))[True].__name__
            raise TypeError('__statics__ items must be strings, not {0}'.format(typ))
        # Move any previously existing, not overridden statics to the static var parent class(es)
        if len(cls.__sro__) > 1:
            for attr,value in namespace.items():
                if attr not in StaticVarsMeta.statics[cls] and attr != ['__statics__']:
                    for c in cls.__sro__[1:]:
                        if attr in StaticVarsMeta.statics[c]:
                            setattr(c,attr,value)
                            delattr(cls,attr)
        return cls
    def __inst_getattribute__(self, orig_getattribute):
        '''Replaces the class __getattribute__'''
        @wraps(orig_getattribute)
        def wrapper(self, attr):
            if StaticVarsMeta.is_static(type(self),attr):
                return StaticVarsMeta.__getstatic__(type(self),attr)
            else:
                return orig_getattribute(self, attr)
        return wrapper
    def __inst_setattr__(self, orig_setattribute):
        '''Replaces the class __setattr__'''
        @wraps(orig_setattribute)
        def wrapper(self, attr, value):
            if StaticVarsMeta.is_static(type(self),attr):
                StaticVarsMeta.__setstatic__(type(self),attr, value)
            else:
                orig_setattribute(self, attr, value)
        return wrapper
    def __inst_delattr__(self, orig_delattribute):
        '''Replaces the class __delattr__'''
        @wraps(orig_delattribute)
        def wrapper(self, attr):
            if StaticVarsMeta.is_static(type(self),attr):
                StaticVarsMeta.__delstatic__(type(self),attr)
            else:
                orig_delattribute(self, attr)
        return wrapper
    def __getstatic__(cls,attr):
        '''Static variable getter'''
        for c in cls.__sro__:
            if attr in StaticVarsMeta.statics[c]:
                try:
                    return getattr(c,attr)
                except AttributeError:
                    pass
        raise AttributeError(cls.__name__ + " object has no attribute '{0}'".format(attr))
    def __setstatic__(cls,attr,value):
        '''Static variable setter'''
        for c in cls.__sro__:
            if attr in StaticVarsMeta.statics[c]:
                setattr(c,attr,value)
                break
    def __delstatic__(cls,attr):
        '''Static variable deleter'''
        for c in cls.__sro__:
            if attr in StaticVarsMeta.statics[c]:
                try:
                    delattr(c,attr)
                    break
                except AttributeError:
                    pass
        raise AttributeError(cls.__name__ + " object has no attribute '{0}'".format(attr))
    def __delattr__(cls,attr):
        '''Prevent __sro__ attribute from deletion'''
        if attr == '__sro__':
            raise AttributeError('readonly attribute')
        super().__delattr__(attr)
    def is_static(cls,attr):
        '''Returns True if an attribute is a static variable of any class in the __sro__'''
        if any(attr in StaticVarsMeta.statics[c] for c in cls.__sro__):
            return True
        return False

මම ඔබේ මාර්ගය භාවිතා කිරීමට උත්සාහ කළ නමුත් මම ගැටලුවකට මුහුණ දුන්නෙමි, කරුණාකර මගේ ප්‍රශ්නය දෙස බලන්න stackoverflow.com/questions/29329850/get-static-variable-value
මුහම්මද් රීෆාට්

IckRickTeachey: මම සාමාන්‍යයෙන් ඔබ පන්තියේදී කරන ඕනෑම දෙයක් Test(එය ක්ෂණික අවස්ථා සඳහා භාවිතා කිරීමට පෙර) මෙටා-ක්‍රමලේඛන වසමේ සිටින බව දැකිය යුතුද? නිදසුනක් ලෙස, ඔබ පන්ති හැසිරීම වෙනස් කිරීමෙන් වෙනස් කරයි Test.i = 0(මෙහිදී ඔබ හුදෙක් දේපල වස්තුව මුළුමනින්ම විනාශ කරයි). මම හිතන්නේ "දේපල-යාන්ත්‍රණය" ආරම්භ වන්නේ පන්තියක අවස්ථාවන්හිදී දේපල ප්‍රවේශය මත පමණි (ඔබ මෙටා පන්තියක් අතරමැදියෙකු ලෙස භාවිතා කරමින් යටින් පවතින හැසිරීම වෙනස් නොකරන්නේ නම්, සමහර විට). Btw, කරුණාකර මෙම පිළිතුර අවසන් කරන්න :-)
ඔලේ තොම්සන් බුවස්

1
IckRickTeachey ස්තූතියි :-) අවසානයේ ඔබේ මෙටැක්ලාස් සිත්ගන්නා සුළු නමුත් ඇත්ත වශයෙන්ම මගේ රුචිකත්වයට එය ටිකක් සංකීර්ණයි. මෙම යාන්ත්‍රණය අත්‍යවශ්‍ය වන විශාල රාමුවක / යෙදුමක එය ප්‍රයෝජනවත් විය හැකිය. කෙසේ වෙතත්, මෙය නිදර්ශනය කරන්නේ නව (සංකීර්ණ) පෙරනිමි නොවන මෙටා-හැසිරීම සැබවින්ම අවශ්‍ය නම්, පයිතන් එය කළ හැකි බවයි :)
ඔලේ තොම්සන් බුවස්

1
LeOleThomsenBuus: කාර්යය කරන සරල මෙටැක්ලාස් සඳහා මගේ පිළිතුර පරීක්ෂා කරන්න .
ඊතන් ෆුරමන්

1
ඔබ නිවැරදි ය; ගැටලුව විසඳීම සඳහා මම පිළිතුර සංස්කරණය කර ඇත්තෙමි (එය මෙතරම් කාලයක් වැරදි ලෙස වාඩි වී ඇති බව විශ්වාස කළ නොහැක!). ව්යාකූලත්වයට කණගාටුයි.
රික් මොනිකාට සහය දක්වයි

33

ඔබට පියාසර කරන පන්තිවලට පන්ති විචල්‍යයන් එකතු කළ හැකිය

>>> class X:
...     pass
... 
>>> X.bar = 0
>>> x = X()
>>> x.bar
0
>>> x.foo
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
AttributeError: X instance has no attribute 'foo'
>>> X.foo = 1
>>> x.foo
1

පංති අවස්ථාවන්ට පන්ති විචල්‍යයන් වෙනස් කළ හැකිය

class X:
  l = []
  def __init__(self):
    self.l.append(1)

print X().l
print X().l

>python test.py
[1]
[1, 1]

3
පංතිය වෙනත් මොඩියුලයකට ආනයනය කළද නව පන්ති විචල්‍යයන් පවතිනු ඇත්ද?
zakdances

ඔව්. ඔබ ඒවා නම් කරන අවකාශය නොසලකා පන්ති effectively ලදායී ලෙස තනි බොත්තම් වේ.
පේද්‍රෝ

Reg ග්‍රෙගරි ඔබ පැවසූ පරිදි “සහ පන්ති අවස්ථාවන්ට පන්ති විචල්‍යයන් වෙනස් කළ හැකිය” ඇත්ත වශයෙන්ම මෙම උදාහරණය ප්‍රවේශය නොව වෙනස් කිරීම ලෙස හැඳින්වේ. වෙනස් කිරීම සිදු කරනු ලැබුවේ වස්තුව විසින්ම එහි උපග්‍රන්ථ () ශ්‍රිතයෙනි.
අම්ර් අල්හෝසරි

19

මට ස්ථිතික ක්‍රමයක් අවශ්‍ය විටෙක මම පෞද්ගලිකව පන්ති ක්‍රමයක් භාවිතා කරමි. ප්රධාන වශයෙන් මම පන්තිය තර්කයක් ලෙස ලබා ගන්නා බැවිනි.

class myObj(object):
   def myMethod(cls)
     ...
   myMethod = classmethod(myMethod) 

හෝ සැරසිලි කරුවෙකු භාවිතා කරන්න

class myObj(object):
   @classmethod
   def myMethod(cls)

ස්ථිතික ගුණාංග සඳහා .. එහි වේලාව ඔබ යම් පයිතන් අර්ථ දැක්වීමක් බැලූ විට .. විචල්‍යය සැමවිටම වෙනස් විය හැකිය. ඒවා විකෘති හා වෙනස් කළ නොහැකි ආකාර දෙකකි .. එසේම, පන්ති ගුණාංග සහ නිදර්ශන ගුණාංග ඇත .. ජාවා සහ සී ++ යන අර්ථයෙන් ස්ථිතික ගුණාංග මෙන් කිසිවක් නැත

පංතියට කිසිදු සම්බන්ධයක් නොමැති නම්, පයිතොනික් අර්ථයෙන් ස්ථිතික ක්‍රමය භාවිතා කරන්නේ ඇයි! මම ඔබ නම්, මම පන්ති ක්‍රමය භාවිතා කරමි, නැතහොත් පන්තියෙන් ස්වාධීන ක්‍රමය නිර්වචනය කරමි.


1
විචල්යයන් විකෘති හෝ වෙනස් කළ නොහැකි ය; වස්තූන් වේ. (කෙසේ වෙතත්, වස්තුවකට විවිධාකාර සාර්ථකත්වයන් සහිතව, එහි ඇතැම් ගුණාංගවලට පැවරීම වැළැක්වීමට උත්සාහ කළ හැකිය.)
ඩේවිස් හෙරින්ග්

ජාවා සහ සී ++ ඔබ නිදර්ශන එදිරිව පන්ති ගුණාංග භාවිතා කරන ආකාරයටම ස්ථිතික (වචනය වැරදි ලෙස භාවිතා කිරීම, ඉමෝ) භාවිතා කරයි. පංති ගුණාංගයක් / ක්‍රමයක් ජාවා සහ සී ++ වල ස්ථිතික වේ, වෙනසක් නැත, පයිතන්හි පන්ති ක්‍රම ඇමතුමක පළමු පරාමිතිය පන්තිය වේ.
ඒන්ජල් ඕස්පියර්

16

ස්ථිතික ගුණාංග සහ නිදර්ශන ගුණාංග ගැන සටහන් කළ යුතු එක් විශේෂ දෙයක්, පහත උදාහරණයේ පෙන්වා ඇත:

class my_cls:
  my_prop = 0

#static property
print my_cls.my_prop  #--> 0

#assign value to static property
my_cls.my_prop = 1 
print my_cls.my_prop  #--> 1

#access static property thru' instance
my_inst = my_cls()
print my_inst.my_prop #--> 1

#instance property is different from static property 
#after being assigned a value
my_inst.my_prop = 2
print my_cls.my_prop  #--> 1
print my_inst.my_prop #--> 2

මෙයින් අදහස් වන්නේ නිදර්ශන දේපල සඳහා අගය පැවරීමට පෙර, අපි දේපල හරහා ප්‍රවේශ වීමට උත්සාහ කරන්නේ නම්, ස්ථිතික අගය භාවිතා වේ. පයිතන් පංතියේ ප්‍රකාශිත සෑම දේපලකම සෑම විටම මතකයේ ස්ථිතික තව් ඇත .


16

පයිතන්හි ස්ථිතික ක්‍රම classmethod s ලෙස හැඳින්වේ . පහත කේතය දෙස බලන්න

class MyClass:

    def myInstanceMethod(self):
        print 'output from an instance method'

    @classmethod
    def myStaticMethod(cls):
        print 'output from a static method'

>>> MyClass.myInstanceMethod()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method myInstanceMethod() must be called [...]

>>> MyClass.myStaticMethod()
output from a static method

මෙම ක්‍රමය myInstanceMethod ලෙස හැඳින්වූ විට අපට දෝෂයක් ඇති බව සලකන්න . මෙයට හේතුව මෙම පන්තියේ නිදසුනක් මත එම ක්‍රමය කැඳවීම අවශ්‍ය වීමයි. MyStaticMethod ක්‍රමය සැරසිලි @classmethod භාවිතා කරමින් පන්ති ක්‍රමයක් ලෙස සකසා ඇත .

කික්ස් සහ ගිග්ල්ස් සඳහා, පංතියේ උදාහරණයක් පසුකර යාමෙන් අපට පන්තියේදී මගේ ඉන්ස්ටාන්ස් ක්‍රමය අමතන්න :

>>> MyClass.myInstanceMethod(MyClass())
output from an instance method

2
ම්ම් ... ස්ථිතික ක්‍රම සමඟ සාදා ඇත @staticmethod; @classmethod(පැහැදිලිවම) පන්ති ක්‍රම සඳහා (ඒවා මූලික වශයෙන් විකල්ප ඉදිකිරීම්කරුවන් ලෙස භාවිතා කිරීමට අදහස් කරන නමුත් ඒවා පන්ච් වෙත යොමු කිරීමක් ලැබිය හැකි ස්ථිතික ක්‍රම ලෙස සැළකිය හැකිය).
ෂැඩෝ රේන්ජර්

11

ඕනෑම සාමාජික ක්‍රමයකට පිටින් යම් සාමාජික විචල්‍යයක් නිර්වචනය කරන විට, විචල්‍යය ප්‍රකාශ වන ආකාරය අනුව විචල්‍යය ස්ථිතික හෝ ස්ථිතික නොවන විය හැකිය.

  • CLASSNAME.var ස්ථිතික විචල්‍යයයි
  • INSTANCENAME.var ස්ථිතික විචල්‍ය නොවේ.
  • පංතිය තුළ self.var ස්ථිතික විචල්‍ය නොවේ.
  • var පන්තියේ සාමාජික ශ්‍රිතය තුළ අර්ථ දක්වා නොමැත.

උදාහරණයක් වශයෙන්:

#!/usr/bin/python

class A:
    var=1

    def printvar(self):
        print "self.var is %d" % self.var
        print "A.var is %d" % A.var


    a = A()
    a.var = 2
    a.printvar()

    A.var = 3
    a.printvar()

ප්‍රති results ල වේ

self.var is 2
A.var is 1
self.var is 2
A.var is 3

ඉන්ඩෙන්ටරය කැඩී ඇත. මෙය ක්‍රියාත්මක නොවේ
තෝමස් වෙල්ලර්

10

staticපන්ති විචල්‍යයන් තිබිය හැකි නමුත් බොහෝ විට උත්සාහය වටින්නේ නැත.

පයිතන් 3 හි ලියා ඇති සංකල්පය සනාථ කිරීමේ සාක්ෂියක් මෙන්න - කිසියම් නිශ්චිත විස්තරයක් වැරදියි නම්, ඔබ අදහස් කරන ඕනෑම දෙයකට ගැලපෙන පරිදි කේතය වෙනස් කළ හැකිය static variable:


class Static:
    def __init__(self, value, doc=None):
        self.deleted = False
        self.value = value
        self.__doc__ = doc
    def __get__(self, inst, cls=None):
        if self.deleted:
            raise AttributeError('Attribute not set')
        return self.value
    def __set__(self, inst, value):
        self.deleted = False
        self.value = value
    def __delete__(self, inst):
        self.deleted = True

class StaticType(type):
    def __delattr__(cls, name):
        obj = cls.__dict__.get(name)
        if isinstance(obj, Static):
            obj.__delete__(name)
        else:
            super(StaticType, cls).__delattr__(name)
    def __getattribute__(cls, *args):
        obj = super(StaticType, cls).__getattribute__(*args)
        if isinstance(obj, Static):
            obj = obj.__get__(cls, cls.__class__)
        return obj
    def __setattr__(cls, name, val):
        # check if object already exists
        obj = cls.__dict__.get(name)
        if isinstance(obj, Static):
            obj.__set__(name, val)
        else:
            super(StaticType, cls).__setattr__(name, val)

සහ භාවිතයේ පවතී:

class MyStatic(metaclass=StaticType):
    """
    Testing static vars
    """
    a = Static(9)
    b = Static(12)
    c = 3

class YourStatic(MyStatic):
    d = Static('woo hoo')
    e = Static('doo wop')

සහ සමහර පරීක්ෂණ:

ms1 = MyStatic()
ms2 = MyStatic()
ms3 = MyStatic()
assert ms1.a == ms2.a == ms3.a == MyStatic.a
assert ms1.b == ms2.b == ms3.b == MyStatic.b
assert ms1.c == ms2.c == ms3.c == MyStatic.c
ms1.a = 77
assert ms1.a == ms2.a == ms3.a == MyStatic.a
ms2.b = 99
assert ms1.b == ms2.b == ms3.b == MyStatic.b
MyStatic.a = 101
assert ms1.a == ms2.a == ms3.a == MyStatic.a
MyStatic.b = 139
assert ms1.b == ms2.b == ms3.b == MyStatic.b
del MyStatic.b
for inst in (ms1, ms2, ms3):
    try:
        getattr(inst, 'b')
    except AttributeError:
        pass
    else:
        print('AttributeError not raised on %r' % attr)
ms1.c = 13
ms2.c = 17
ms3.c = 19
assert ms1.c == 13
assert ms2.c == 17
assert ms3.c == 19
MyStatic.c = 43
assert ms1.c == 13
assert ms2.c == 17
assert ms3.c == 19

ys1 = YourStatic()
ys2 = YourStatic()
ys3 = YourStatic()
MyStatic.b = 'burgler'
assert ys1.a == ys2.a == ys3.a == YourStatic.a == MyStatic.a
assert ys1.b == ys2.b == ys3.b == YourStatic.b == MyStatic.b
assert ys1.d == ys2.d == ys3.d == YourStatic.d
assert ys1.e == ys2.e == ys3.e == YourStatic.e
ys1.a = 'blah'
assert ys1.a == ys2.a == ys3.a == YourStatic.a == MyStatic.a
ys2.b = 'kelp'
assert ys1.b == ys2.b == ys3.b == YourStatic.b == MyStatic.b
ys1.d = 'fee'
assert ys1.d == ys2.d == ys3.d == YourStatic.d
ys2.e = 'fie'
assert ys1.e == ys2.e == ys3.e == YourStatic.e
MyStatic.a = 'aargh'
assert ys1.a == ys2.a == ys3.a == YourStatic.a == MyStatic.a

8

මෙටාක්ලාස් භාවිතයෙන් පන්තියක් ස්ථිතික වීමට ඔබට බල කළ හැකිය.

class StaticClassError(Exception):
    pass


class StaticClass:
    __metaclass__ = abc.ABCMeta

    def __new__(cls, *args, **kw):
        raise StaticClassError("%s is a static class and cannot be initiated."
                                % cls)

class MyClass(StaticClass):
    a = 1
    b = 3

    @staticmethod
    def add(x, y):
        return x+y

අහම්බෙන් ඔබ MyClass ආරම්භ කිරීමට උත්සාහ කරන සෑම විටම ඔබට StaticClassError එකක් ලැබෙනු ඇත.


4
ඔබ එය ක්ෂණිකව ක්‍රියාත්මක නොකරන්නේ නම් එය පන්තියක් වන්නේ ඇයි? මෙය ජාවා බවට හැරවීම සඳහා පයිතන් ඇඹරීම මෙන් දැනේ ....
නෙඩ් බැට්චෙල්ඩර්

1
මෙය හැසිරවීමට වඩා හොඳ ක්‍රමයක් වන්නේ බෝර්ග් මෝඩය .
රික් මොනිකා

EdNedBatchelder එය වියුක්ත පන්තියක් වන අතර එය උප පංති සඳහා පමණක් (සහ උප පංති
ස්ථාපනය කිරීම සඳහා

1
මම හිතන්නේ උප පංති __new__එහි දෙමව්පියන්ගේ ආයාචනය සඳහා සුපිරි () භාවිතා නොකරයි ...
නෙඩ් බැට්චෙල්ඩර්

7

පයිතන්ගේ ගුණාංග සෙවීම පිළිබඳ ඉතා සිත්ගන්නා කරුණක් නම් එය “ අතථ්‍ය විචල්‍යයන්” නිර්මාණය කිරීමට භාවිතා කළ හැකි බවයි :

class A(object):

  label="Amazing"

  def __init__(self,d): 
      self.data=d

  def say(self): 
      print("%s %s!"%(self.label,self.data))

class B(A):
  label="Bold"  # overrides A.label

A(5).say()      # Amazing 5!
B(3).say()      # Bold 3!

සාමාන්‍යයෙන් මේවා නිර්මාණය කිරීමෙන් පසු කිසිදු පැවරුමක් නොමැත. මෙම බැලීම බඹුන් සටහන selfනිසා වුවත් labelඒ සමඟ ලබාදෙන්නේ නැහැ අර්ථයෙන් ස්ථිතික විශේෂයෙන් උදාහරණයක් වශයෙන්, වටිනාකම අවස්ථාවේ දී, (පන්ති) මත තවමත් රඳා පවතී.


6

මෙම පිළිතුර සම්බන්ධයෙන් , නියත ස්ථිතික විචල්‍යයක් සඳහා, ඔබට විස්තරයක් භාවිතා කළ හැකිය. මෙන්න උදාහරණයක්:

class ConstantAttribute(object):
    '''You can initialize my value but not change it.'''
    def __init__(self, value):
        self.value = value

    def __get__(self, obj, type=None):
        return self.value

    def __set__(self, obj, val):
        pass


class Demo(object):
    x = ConstantAttribute(10)


class SubDemo(Demo):
    x = 10


demo = Demo()
subdemo = SubDemo()
# should not change
demo.x = 100
# should change
subdemo.x = 100
print "small demo", demo.x
print "small subdemo", subdemo.x
print "big demo", Demo.x
print "big subdemo", SubDemo.x

මෙහි ප්රතිඵලයක් ලෙස ...

small demo 10
small subdemo 100
big demo 10
big subdemo 10

සැකසීමේ අගය ( passඉහළ) නිහ ly ව නොසලකා හැරීම ඔබේ දෙයක් නොවේ නම් ඔබට සැමවිටම ව්‍යතිරේකයක් මතු කළ හැකිය . ඔබ C ++ සොයන්නේ නම්, ජාවා විලාසිතාවේ ස්ථිතික පන්ති විචල්‍යය:

class StaticAttribute(object):
    def __init__(self, value):
        self.value = value

    def __get__(self, obj, type=None):
        return self.value

    def __set__(self, obj, val):
        self.value = val

විස්තර කරන්නන් පිළිබඳ වැඩි විස්තර සඳහා මෙම පිළිතුර සහ නිල ලේඛනය HOWTO දෙස බලන්න .


2
ඔබට භාවිතා කළ හැකිය @property, එය විස්තර කරන්නෙකු භාවිතා කිරීම හා සමාන වේ, නමුත් එය බොහෝ අඩු කේතයකි.
රික් මොනිකාට සහාය දක්වයි

6

නියත වශයෙන්ම ඔව්, පයිතන්ට නිශ්චිතවම ස්ථිතික දත්ත සාමාජිකයෙකු නොමැත, නමුත් එසේ කිරීමෙන් අපට තිබිය හැකිය

class A:
    counter =0
    def callme (self):
        A.counter +=1
    def getcount (self):
        return self.counter  
>>> x=A()
>>> y=A()
>>> print(x.getcount())
>>> print(y.getcount())
>>> x.callme() 
>>> print(x.getcount())
>>> print(y.getcount())

ප්‍රතිදානය

0
0
1
1

පැහැදිලි කිරීම

here object (x) alone increment the counter variable
from 0 to 1 by not object y. But result it as "static counter"

6

ඔව්, නියත වශයෙන්ම පයිතන්හි ස්ථිතික විචල්‍යයන් සහ ක්‍රම ලිවිය හැකිය.

ස්ථිතික විචල්යයන්: පන්ති මට්ටමින් ප්රකාශයට පත් කරන ලද විචල්යය ස්ථිතික විචල්ය ලෙස හැඳින්වෙන අතර ඒවා පන්ති නාමයෙන් කෙලින්ම ප්රවේශ විය හැකිය.

    >>> class A:
        ...my_var = "shagun"

    >>> print(A.my_var)
        shagun

නිදර්ශන විචල්‍යයන්: පන්තියක උදාහරණයකට සම්බන්ධ හා ප්‍රවේශ විය හැකි විචල්‍යයන් නිදර්ශන විචල්‍යයන් වේ.

   >>> a = A()
   >>> a.my_var = "pruthi"
   >>> print(A.my_var,a.my_var)
       shagun pruthi

ස්ථිතික ක්‍රම: විචල්‍යයන්ට සමානව, ස්ථිතික ක්‍රම පංති නාමයෙන් කෙලින්ම ප්‍රවේශ විය හැකිය. උදාහරණයක් නිර්මාණය කිරීමට අවශ්‍ය නැත.

නමුත් මතක තබා ගන්න, ස්ථිතික ක්‍රමයකට පයිතන්හි ස්ථිතික නොවන ක්‍රමයක් හැඳින්විය නොහැක.

    >>> class A:
   ...     @staticmethod
   ...     def my_static_method():
   ...             print("Yippey!!")
   ... 
   >>> A.my_static_method()
   Yippey!!

4

විභව ව්‍යාකූලත්වයක් ඇතිවීම වලක්වා ගැනීම සඳහා, ස්ථිතික විචල්‍යයන් සහ වෙනස් කළ නොහැකි වස්තූන් අතර වෙනස දැක්වීමට මම කැමැත්තෙමි.

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

විචල්ය ස්ථිතිකයක් සෑදීමෙන් මෙය තවත් පියවරක් ඉදිරියට ගෙන යන්නේ විචල්ය නාමය ඕනෑම වස්තුවකට යොමු කිරීමට ඉඩ නොදීමෙන් නමුත් එය දැනට පෙන්වා ඇති දෙයට ය. (සටහන: මෙය සාමාන්‍ය මෘදුකාංග සංකල්පයක් වන අතර එය පයිතන්ට විශේෂිත නොවේ; කරුණාකර පයිතන්හි සංඛ්‍යාන ක්‍රියාත්මක කිරීම පිළිබඳ තොරතුරු සඳහා අනෙක් අයගේ සටහන් බලන්න).


4

මා සොයාගත් හොඳම ක්‍රමය වෙනත් පන්තියක් භාවිතා කිරීමයි. ඔබට වස්තුවක් නිර්මාණය කර වෙනත් වස්තූන් මත භාවිතා කළ හැකිය.

class staticFlag:
    def __init__(self):
        self.__success = False
    def isSuccess(self):
        return self.__success
    def succeed(self):
        self.__success = True

class tryIt:
    def __init__(self, staticFlag):
        self.isSuccess = staticFlag.isSuccess
        self.succeed = staticFlag.succeed

tryArr = []
flag = staticFlag()
for i in range(10):
    tryArr.append(tryIt(flag))
    if i == 5:
        tryArr[i].succeed()
    print tryArr[i].isSuccess()

ඉහත උදාහරණය සමඟ මම පන්තියක් හැදුවා staticFlag .

මෙම පන්තිය ස්ථිතික var ඉදිරිපත් කළ යුතුය __success (පුද්ගලික ස්ථිතික Var) .

tryIt පන්තිය නියෝජනය කළේ අප භාවිතා කළ යුතු සාමාන්‍ය පන්තියයි.

දැන් මම එක් ධජයක් සඳහා වස්තුවක් සාදන ලදී (staticFlag ). මෙම ධජය සියලුම නිත්‍ය වස්තූන් වෙත යොමු කරනු ලැබේ.

මෙම සියලු වස්තු ලැයිස්තුවට එකතු වේ tryArr.


මෙම ස්ක්‍රිප්ට් ප්‍රති Results ල:

False
False
False
False
False
True
True
True
True
True

2

පන්ති කර්මාන්තශාලාවේ ස්ථිතික විචල්‍යයන් python3.6

පයිතන් 3.6 සහ ඊට ඉහළ පන්ති කර්මාන්ත ශාලාවක් භාවිතා කරන ඕනෑම කෙනෙකුට nonlocalඑය නිර්මාණය කරන පන්තියේ විෂය පථයට / සන්දර්භයට එක් කිරීමට යතුරු පදය භාවිතා කරන්න:

>>> def SomeFactory(some_var=None):
...     class SomeClass(object):
...         nonlocal some_var
...         def print():
...             print(some_var)
...     return SomeClass
... 
>>> SomeFactory(some_var="hello world").print()
hello world

ඔව්, නමුත් මේ අවස්ථාවේ දී hasattr(SomeClass, 'x')False. ස්ථිතික විචල්‍යයකින් කිසිවෙකු අදහස් කරන්නේ මෙයදැයි මට සැකයි.
රික් මොනිකා

IckRickTeachey lol, ඔබේ ස්ථිතික විචල්ය කේතය, stackoverflow.com/a/27568860/2026508 +1 අන්තර්ජාල සර් දුටුවා , මම හිතුවේ හසාත්ර් ඒ වගේ වැඩ කරන්නේ නැහැ කියලද? එසේ some_varනොවෙනස්ව පවතින අතර සංඛ්‍යාත්මකව අර්ථ දක්වා තිබේද? එසේ නොවේද? විචල්‍යයක් ස්ථිතිකද නැද්ද යන්න සමඟ බාහිර ලබා ගන්නන්ගේ ප්‍රවේශයට ඇති සම්බන්ධය කුමක්ද? මට දැන් බොහෝ ප්‍රශ්න තිබේ. ඔබට කාලය ලැබුණු විට පිළිතුරු කිහිපයක් ඇසීමට කැමතියි.
jmunsch

ඔව්, මෙටාක්ලාස් ඉතා හාස්‍යජනකයි. මට ප්‍රශ්න තේරෙන බව මට විශ්වාස නැත, නමුත් මගේ මතකයට අනුව, some_varඉහත පංතියේ සාමාජිකයෙක් නොවේ. පයිතන් හි සියලුම පන්ති සාමාජිකයින්ට පන්තියෙන් පිටත සිට ප්‍රවේශ විය හැකිය.
රික් මොනිකා

මෙම nonlocalkeywoard විචල්ය හි විෂය පථය "ගැටිති". පංති ශරීර අර්ථ දැක්වීමේ විෂය පථය එය සොයා ගන්නා විෂය පථයෙන් ස්වාධීන වේ- ඔබ කියන විට nonlocal some_var, එය හුදෙක් දේශීය නොවන (කියවීම: පන්ති අර්ථ දැක්වීමේ විෂය පථයේ නොවේ) වෙනත් නම් කරන ලද වස්තුවකට නම යොමු කිරීමකි. එබැවින් එය පන්ති අර්ථ දැක්වීමට සම්බන්ධ නොවන්නේ එය පන්ති ශරීර විෂය පථයට අයත් නොවන බැවිනි.
රික් මොනිකා

1

ඉතින් මෙය බොහෝ විට හැක් එකක් විය හැකි නමුත් මම භාවිතා කර ඇත eval(str) පයිතන් 3 හි ස්ථිතික වස්තුවක් ලබා ගැනීමට කර .

classසමහර තර්ක සුරකින ස්ථිතික ක්‍රම සහ ඉදිකිරීම්කරුවන් සමඟ අර්ථ දක්වා ඇති වස්තූන් හැර වෙනත් කිසිවක් නොමැති Records.py ගොනුවක් ඇත . වෙනත් .py ගොනුවකින් මම import Recordsනමුත් මට අවශ්‍ය වන්නේ එක් එක් වස්තුව ගතිකව තෝරාගෙන කියවන දත්ත වර්ගය අනුව ඉල්ලුම මත එය ක්ෂණිකව සකස් කිරීමයි.

ඉතින් කොහේද object_name = 'RecordOne'හෝ පංතියේ නම, මම අමතන්න cur_type = eval(object_name), පසුව එය කරන්න. cur_inst = cur_type(args) කෙසේ වෙතත් ඔබ ක්ෂණික වීමට පෙර ඔබට ස්ථිතික ක්‍රම ඇමතිය හැකිය cur_type.getName(), උදාහරණයක් ලෙස, වියුක්ත පාදක පන්ති ක්‍රියාත්මක කිරීම හෝ ඉලක්කය කුමක් වුවත්. කෙසේ වෙතත්, පසුබිම තුළ, එය බොහෝ විට පයිතන් වලින් ක්ෂණිකව පිහිටුවා ඇති අතර එය ඇත්ත වශයෙන්ම ස්ථිතික නොවේ, මන්ද එවාල් වස්තුවක් ආපසු ලබා දෙන බැවිනි .... එය ක්ෂණිකව තිබිය යුතුය .... එය ස්ථිතික හැසිරීම් ලබා දෙයි.


0

අවස්ථා අතර “ස්ථිතික හැසිරීම” ලබා ගැනීමට ඔබට ලැයිස්තුවක් හෝ ශබ්ද කෝෂයක් භාවිතා කළ හැකිය.

class Fud:

     class_vars = {'origin_open':False}

     def __init__(self, origin = True):
         self.origin = origin
         self.opened = True
         if origin:
             self.class_vars['origin_open'] = True


     def make_another_fud(self):
         ''' Generating another Fud() from the origin instance '''

         return Fud(False)


     def close(self):
         self.opened = False
         if self.origin:
             self.class_vars['origin_open'] = False


fud1 = Fud()
fud2 = fud1.make_another_fud()

print (f"is this the original fud: {fud2.origin}")
print (f"is the original fud open: {fud2.class_vars['origin_open']}")
# is this the original fud: False
# is the original fud open: True

fud1.close()

print (f"is the original fud open: {fud2.class_vars['origin_open']}")
# is the original fud open: False

0

ඔබ ස්ථිතික විචල්‍යයක් බෙදා ගැනීමට උත්සාහ කරන්නේ නම්, උදාහරණයක් ලෙස, එය වෙනත් අවස්ථා හරහා වැඩි කිරීම, මෙම ස්ක්‍රිප්ට් වැනි දෙයක් හොඳින් ක්‍රියාත්මක වේ:

# -*- coding: utf-8 -*-
class Worker:
    id = 1

    def __init__(self):
        self.name = ''
        self.document = ''
        self.id = Worker.id
        Worker.id += 1

    def __str__(self):
        return u"{}.- {} {}".format(self.id, self.name, self.document).encode('utf8')


class Workers:
    def __init__(self):
        self.list = []

    def add(self, name, doc):
        worker = Worker()
        worker.name = name
        worker.document = doc
        self.list.append(worker)


if __name__ == "__main__":
    workers = Workers()
    for item in (('Fiona', '0009898'), ('Maria', '66328191'), ("Sandra", '2342184'), ('Elvira', '425872')):
        workers.add(item[0], item[1])
    for worker in workers.list:
        print(worker)
    print("next id: %i" % Worker.id)
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.