පයිතන් හි නියතයක් නිර්මාණය කරන්නේ කෙසේද?


1030

පයිතන්හි නියතයක් ප්‍රකාශ කිරීමට ක්‍රමයක් තිබේද? ජාවා හි අපට මේ ආකාරයෙන් නියත අගයන් නිර්මාණය කළ හැකිය:

public static final String CONST_NAME = "Name";

පයිතන් හි ඉහත ජාවා නියත ප්‍රකාශයට සමාන වන්නේ කුමක්ද?


6
ඇත්ත වශයෙන්ම කියවීමට-පමණක් විචල්‍යයන් සෑදිය හැකි ක්‍රමය පයිතන්ගේ දේපල ක්‍රියාකාරිත්වය / සැරසිලි කරුවෙකු හරහා කළ හැකිය . මෙම පිළිතුරINV ඒ චාරිත්රයක් භාවිතය සඳහා උදාහරණ වේ. දේපල ඊට වඩා සාමාන්‍ය භාවිතයකි, කෙසේ වෙතත්, එය ක්‍රියා කරන ආකාරය පිළිබඳ හොඳ විශ්ලේෂණයක් ෂලාබ් චතුර්වේදිගේ පයිතන් ගුණාංග සහ ක්‍රම මත වේ.
n611x007

21
IMHO, නියතතාව බලාත්මක කිරීම "පයිතොනික් නොවේ". පයිතන් 2.7 හි ඔබට ලිවිය හැකිය True=False, පසුව (2+2==4)==Trueනැවත පැමිණේ False.
osa

8
වෙනත් පිළිතුරු වලට අනුව නියතයන් ප්‍රකාශ කිරීමට ක්‍රමයක් හෝ අවශ්‍යතාවයක් නොමැත. නමුත් සම්මුතීන් ගැන ඔබට මෙම PEP කියවිය හැකිය . උදා: THIS_IS_A_CONSTANT
රසිකා පෙරේරා

36
@osa: ඔබට පයිතන් 3 හි එය කළ නොහැක SyntaxError: can't assign to keyword. මෙය හොඳ දෙයක් සේ පෙනේ.
naught101

3
පුදුමයට කරුණක් නම් මේ වන තෙක් මෙය සඳහන් කර නොමැති නමුත් ගණන් බලා ඇති නියතයන් නිර්වචනය කිරීමට හොඳ ක්‍රමයක් ලෙස එනුම්ස් පෙනේ.
cs95

Answers:


1008

නැත. ඔබට පයිතන් හි විචල්‍යයක් හෝ අගයක් නියතයක් ලෙස ප්‍රකාශ කළ නොහැක. එය වෙනස් නොකරන්න.

ඔබ පන්තියක සිටී නම්, සමාන වන්නේ:

class Foo(object):
    CONST_NAME = "Name"

එසේ නොවේ නම් එය සාධාරණ ය

CONST_NAME = "Name"

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


පයිතන් 3.8 වන විට, typing.Finalඔබේ විචල්‍යය නැවත පැවරිය යුතු නැති බව ස්ථිතික වර්ග පරීක්ෂකයින්ට (මයිපී වැනි) පවසන විචල්ය විවරණයක් ඇත. මෙය ජාවාට ආසන්නතම සමාන වේ final. කෙසේ වෙතත්, එය නැවත පැවරීම වලක්වනු නොලැබේ :

from typing import Final

a: Final = 1

# Executes fine, but mypy will report an error if you run mypy on this:
a = 2

27
ඒ වෙනුවට "පයිතන්හි නියතයන්" තුළ ඇති දේ කරන්න, ඔබ "දේපල" ශ්‍රිතය හෝ සැරසිලි යන්ත්‍රය භාවිතා කළ යුතුය.
සෙත් ජොන්සන්

27
පර්ල් හි එකම අංගය ගැන මිනිසුන් අසයි. ආනයන මොඩියුලයක් “නියතය භාවිතා කරන්න” යනුවෙන් හැඳින්වේ, නමුත් (AFAIK) යනු අගය ලබා දෙන ඉතා කුඩා ශ්‍රිතයක් නිර්මාණය කිරීම සඳහා වූ එතීමකි. මමත් කරන්නේ පයිතන් වල. උදාහරණය:def MY_CONST_VALUE(): return 123
kevinarpe

9
"නෑ නෑ." ඇත්ත, නමුත් අනෙක් අයගේ වැඩකටයුතු ගොඩනඟා ගනිමින්, මම පයිතන් 2.7 සඳහා “නියතයන්” කෙටියෙන් හා සරල ලෙස ක්‍රියාත්මක කරමින් ඊට වඩා පහළින් පිළිතුරක් එක් කර ඇත්තෙමි. මේවා එනුම් වැනි කියවීමට පමණක් name.attributeවන අතර ඕනෑම අගයක් අඩංගු විය හැකිය. ප්‍රකාශනය පහසුය Nums = Constants(ONE=1, PI=3.14159, DefaultWidth=100.0), භාවිතය සරල ය print 10 + Nums.PI, ව්‍යතිරේකයේ Nums.PI = 22ප්‍රති results ල වෙනස් කිරීමට උත්සාහ කිරීම => අගය දෝෂය (..).
මෙවලම් සාදන්නා

118
එය වෙනස් නොකරන්න. ඔබ මගේ දවස සෑදුවා
හායි-ඒන්ජල්

97
"එය වෙනස් නොකරන්න" කිසිසේත් ප්‍රයෝජනවත් නොවේ. එය ප්‍රශ්නයට පිළිතුරු නොදෙන අතර එය ඉවත් කරන ලෙස මම යෝජනා කරමි.
බාර්ටෙක් බනාචෙවිච්

363

constවෙනත් භාෂාවල මෙන් යතුරු පදයක් නොමැත , කෙසේ වෙතත් දත්ත කියවීම සඳහා "ලබා ගැනීමේ ශ්‍රිතයක්" ඇති දේපලක් නිර්මාණය කළ හැකි නමුත් දත්ත නැවත ලිවීමට "සැකසුම් ශ්‍රිතයක්" නොමැත. මෙය අනන්‍යතාවය වෙනස් කිරීමෙන් ආරක්ෂා කරයි.

පන්ති දේපල භාවිතා කරමින් විකල්ප ක්‍රියාත්මක කිරීමක් මෙන්න:

නියතය ගැන කල්පනා කරන පා er කයාට කේතය පහසු නොවන බව සලකන්න. පහත පැහැදිලි කිරීම බලන්න

def constant(f):
    def fset(self, value):
        raise TypeError
    def fget(self):
        return f()
    return property(fget, fset)

class _Const(object):
    @constant
    def FOO():
        return 0xBAADFACE
    @constant
    def BAR():
        return 0xDEADBEEF

CONST = _Const()

print CONST.FOO
##3131964110

CONST.FOO = 0
##Traceback (most recent call last):
##    ...
##    CONST.FOO = 0
##TypeError: None

කේත පැහැදිලි කිරීම:

  1. constantප්‍රකාශනයක් ගන්නා ශ්‍රිතයක් නිර්වචනය කර එය “ලබා ගන්නෙකු” තැනීමට භාවිතා කරයි - එය ප්‍රකාශනයේ වටිනාකම පමණක් ලබා දෙන ශ්‍රිතයකි.
  2. සැකසුම් ශ්‍රිතය TypeError මතු කරයි, එබැවින් එය කියවීමට පමණි
  3. constantකියවීමට පමණක් ඇති ගුණාංග ඉක්මනින් අර්ථ දැක්වීම සඳහා අපි දැන් සැරසිලි ලෙස නිර්මාණය කළ ශ්‍රිතය භාවිතා කරන්න .

තවත් පැරණි ක්‍රමයකට:

(කේතය තරමක් උපක්‍රමශීලී ය, වැඩි විස්තර පහතින්)

class _Const(object):
    @apply
    def FOO():
        def fset(self, value):
            raise TypeError
        def fget(self):
            return 0xBAADFACE
        return property(**locals())

CONST = _Const()

print CONST.FOO
##3131964110

CONST.FOO = 0
##Traceback (most recent call last):
##    ...
##    CONST.FOO = 0
##TypeError: None

@ Apply සැරසිලි කරුවා ඉවත් කර ඇති බව සලකන්න.

  1. හඳුනාගැනීමේ FOO නිර්වචනය කිරීම සඳහා, firs විසින් ශ්‍රිත දෙකක් අර්ථ දක්වයි (fset, fget - නම් මගේ අභිමතය පරිදි).
  2. ඉන්පසු property"සැකසීමට" හෝ "ලබා ගැනීමට" හැකි වස්තුවක් තැනීම සඳහා සාදන ලද ශ්‍රිතය භාවිතා කරන්න .
  3. සටහන තොප්පිය propertyශ්‍රිතයේ පළමු පරාමිතීන් දෙක නම් කර ඇති fsetඅතර fget.
  4. අපි අපේම තරගයක සහ පන්දු පිරිනමන්නා සඳහා මෙම ඉතා නම් තෝරා බව භාවිතා කරන අතර ** (ද්විත්ව තරු ලකුණ) භාවිතා කරමින් මූල පදයක්-ශබ්ද කෝෂය නිර්මාණය කිරීමට පරාමිති යැවීමට බව විෂය පථය සියලු දේශීය අර්ථ දැක්වීම් යෙදිය propertyඋත්සවය

11
මත ලේඛගතකිරීම මත පදනම් AttributeErrorහා TypeError, මම මතු හැර නව දෝෂයක්, මම නම් කිරීම ද මා යෝජනා කරනවා වන විය යුතු බව හිතන්න ConstantErrorක උපපංතිය වන ඒ වගේ හෝ දෙයක්, TypeError. මා සිතන ආකාරයට ලියකියවිලි කොටස
ArtOfWarfare

3
මෙම කේතය ගැන මම පුදුම වෙමි. FOO () සහ BAR () ක්‍රම අකුරු ස්වයං තර්කයක් ලෙස පවතින්නේ ඇයි? මගේ IDE මඟින් රතු වරහන් ("සම්පාදනය" දෝෂය) අවධාරණය කරයි. මම එය තුළම වෙහෙසට පත් වූ නමුත් පසුව මට දෝෂයක් ඇතිවිය.
user3770060

10
මෙම දිගට යාමෙන් පයිතන් භාෂාවේ පැහැදිලි iency නතාවයක් දක්වයි. මෙය පයිතන් 3 ට එකතු කිරීමේ අවශ්‍යතාවය ඔවුන්ට දැනුනේ නැත්තේ ඇයි? කිසිවෙකු එය යෝජනා නොකළ බව මට විශ්වාස කළ නොහැකි අතර සමහර කමිටුව පිටුපස යන තර්කනය මට නොපෙනේ. නැහැ. '
එස්

8
නිශ්චිත පයිතන් ක්‍රමලේඛකයෙකුට ඔබේ විසඳුම තවමත් වෙනස් කළ හැකියCONST.__dict__['FOO'] = 7
pppery

11
S ඔස්කාර් ස්මිත්, මම හිතන්නේ එය 'ස්වයං ලේඛනගත කේතය' නිර්මාණය වැඩි දියුණු කරනු ඇත. කිසියම් අගයක් වෙනස් කළ නොහැකි කේතයට මා පැහැදිලි කළ විට, සියලු ප්‍රභව කේත කියවා යම් අගයක් කිසි විටෙකත් වෙනස් නොවන බව වටහා ගැනීමට වඩා තේරුම් ගැනීම පහසුය. එසේම, යමෙකු නියත විය යුතු අගයක් වෙනස් කිරීමට ඇති හැකියාව එය අවහිර කරයි. මතක තබා ගන්න: පැහැදිළි කිරීම ව්‍යංගයට වඩා හොඳය.
ගේබ්‍රියෙල්

116

භාෂාවක් බලාත්මක කිරීම වෙනුවට පයිතන්හිදී, මිනිසුන් නම් කිරීමේ සම්මුතීන් උදා __method. පුද්ගලික ක්‍රම සඳහා සහ _methodආරක්ෂිත ක්‍රම සඳහා භාවිතා කරයි.

එබැවින් සෑම ආකාරයකින්ම නියතය ප්‍රකාශ කළ හැකිය

MY_CONSTANT = "one"

මෙම නියතය කිසි විටෙකත් වෙනස් නොවන බව ඔබට අවශ්‍ය නම්, ඔබට ආරෝපණ ප්‍රවේශයට සම්බන්ධ වී උපක්‍රම කළ හැකිය, නමුත් සරල ප්‍රවේශයක් නම් ශ්‍රිතයක් ප්‍රකාශ කිරීමයි

def MY_CONSTANT():
    return "one"

සෑම තැනකම ඇත්තේ ඔබට MY_CONSTANT () කිරීමට සිදුවනු ඇත, නමුත් නැවතත් පයිතන්හි MY_CONSTANT = "one"(සාමාන්‍යයෙන්) නිවැරදි ක්‍රමයයි.

නියතයන් නිර්මාණය කිරීම සඳහා ඔබට නම් කළ ටුපල් භාවිතා කළ හැකිය :

>>> from collections import namedtuple
>>> Constants = namedtuple('Constants', ['pi', 'e'])
>>> constants = Constants(3.14, 2.718)
>>> constants.pi
3.14
>>> constants.pi = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

18
එසේ කිරීමෙන් def MY_CONSTANT(): return "one"කෙනෙකු, පසුව කේතයේ, කිරීම MY_CONSTANT = "two"(හෝ ශ්‍රිතය නැවත ප්‍රකාශ කිරීම) නතර නොවේ.
මැතිව් ෂින්කෙල්

6
Att මැතිව්ස්චින්කෙල් එය සම්මුතිය ගැන වන අතර, MY_CONSTANT වෙනස් කිරීම MY_CONSTANT () භාවිතය වෙනස් නොකරනු ඇත, නමුත් දෝෂයක් ඇති කරයි, සහ පයිතන්හිදී ඔබට කිසිවක් වෙනස් කළ හැකි නම්, දක්ෂ උපක්‍රමයක් මඟින් ඔබව ආරක්ෂා කළ නොහැක.
අනුරග් යුනියාල්

3
නම් කරන ලද ප්‍රවේශය ගෙන ඒමට ස්තූතියි. නිසැකවම නවෝත්පාදනය. මගේ "අදහස් දැක්වීම" ඔබට අදාළ යැයි සිතිය හැකිය .
RayLuo

Att මැතිව්ස්චින්කෙල් ඔබට පයිතන් වලින් ඕනෑම දෙයක් නැවත අර්ථ දැක්විය හැකිය, එබැවින් එය හොඳ කාරණයක් නොවේ.
cslotty

Att මැතිව්ස්චින්කල් අදහස ලිවීම MY_CONSTANT = MY_CONSTANT()නොව MY_CONSTANT()නියතය ලෙස භාවිතා කිරීමයි. ඇත්ත වශයෙන්ම, මෙය. නමුත් මෙය කදිම වන අතර “අපි සියල්ලෝම මෙහි වැඩිහිටියන් වෙමු” යන පයිතන් මූලධර්මයට අනුකූල වේ - එනම්, හොඳ හේතු ඇති විට සහ ඔවුන් කරන්නේ කුමක්දැයි දැන ගැනීමේදී රීතියක් අභිබවා යාමට තීරණය කිරීම සංවර්ධකයාට කලාතුරකින් තහනම් වේ.
jonathan.scholbach

75

මම මෑතකදී ඉතා සංක්ෂිප්ත යාවත්කාලීන කිරීමක් සොයාගෙන ඇති අතර එමඟින් ස්වයංක්‍රීයව අර්ථවත් දෝෂ පණිවිඩ මතු වන අතර ඒ හරහා ප්‍රවේශය වළක්වයි __dict__:

class CONST(object):
    __slots__ = ()
    FOO = 1234

CONST = CONST()

# ----------

print(CONST.FOO)    # 1234

CONST.FOO = 4321              # AttributeError: 'CONST' object attribute 'FOO' is read-only
CONST.__dict__['FOO'] = 4321  # AttributeError: 'CONST' object has no attribute '__dict__'
CONST.BAR = 5678              # AttributeError: 'CONST' object has no attribute 'BAR'

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

සංස්කරණය කරන්න - මුල් විසඳුම

මට බොහෝ විට මෙහි උපක්‍රමයක් මග හැරී ඇත, නමුත් මෙය මට වැඩ කරන බව පෙනේ:

class CONST(object):
    FOO = 1234

    def __setattr__(self, *_):
        pass

CONST = CONST()

#----------

print CONST.FOO    # 1234

CONST.FOO = 4321
CONST.BAR = 5678

print CONST.FOO    # Still 1234!
print CONST.BAR    # Oops AttributeError

උදාහරණය නිර්මාණය කිරීමෙන් මැජික් __setattr__ක්‍රමයට FOOවිචල්‍යය සැකසීමට උත්සාහ කිරීම වළක්වා ගත හැකිය. ඔබට අවශ්‍ය නම් මෙහි ව්‍යතිරේකයක් විසි කළ හැකිය. පංතියේ නමට උඩින් ස්ථාපනය කිරීම පන්තිය හරහා කෙලින්ම ප්‍රවේශ වීම වළක්වයි.

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


11
මෙය හොඳම හා වඩාත්ම පැහැදිලි පිළිතුරයි, මන්ද එයට අවම “යාන්ත්‍රණයක්” ඇත, නමුත් වඩාත්ම ක්‍රියාකාරීත්වය ඇත. ව්යතිරේකයක් මතු කිරීම වැදගත් වුවද ... විකල්පයක් නොවේ.
එරික් ඇරොනෙස්ටි

ස්වයංක්‍රීයව අර්ථවත් දෝෂ ඇති කරන නමුත් එකම ශෛලියකින් යුත් කෙටි මාර්ගයක් මම සකස් කර ඇත්තෙමි. සැසඳීම සඳහා මම මෙහි මුල් අදහස අතහැර දැමුවෙමි.
ජෝන් බෙට්ස්

ඔබට තවමත් මෙම CONST.උපසර්ගය අවශ්‍ය වීම කෙතරම් කණගාටුදායකද ? බහු මොඩියුල අවස්ථාවන්හිදී මෙය සංකීර්ණ වනු ඇත.
ඇල්ෆේ

1
මම හිතන්නේ සාමාන්‍යයෙන් ඔබට යම් තත්වයකදී (එක් යෝධ CONST වස්තුවක් ඇතිවාට වඩා) නියතයන් සම්බන්ධිත මිටි කිහිපයකට කණ්ඩායම් කිරීමට අවශ්‍ය වනු ඇත, එබැවින් එය එතරම් නරක දෙයක් නොවේ.
ජෝන් බෙට්ස්

1
මෙම පිළිතුර තවමත් මෙතරම් පහත වැටෙන්නේ ඇයි? මෙම __slots__විසඳුම එසේ අලංකාර සහ ඵලදායී වේ. මා කියවා ඇති සෑම දෙයකින්ම, මෙය පයිතන් හි නියතයන් නිර්මාණය කිරීමට ආසන්න වේ. බොහොම ස්තූතියි. උනන්දුවක් දක්වන සෑම කෙනෙකුටම, මෙන්න__slots__ මැජික් පිළිබඳ දීප්තිමත් හා ගැඹුරු පැහැදිලි කිරීමක් .
ජෝන්ගෝල්ට්

35

පයිතන්ට නියතයන් නොමැත.

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

def MY_CONSTANT():
    return 42

MY_CONSTANT() දැන් නියතයක සියලු ක්‍රියාකාරීත්වයන් ඇත (ඊට අමතරව සමහර කරදරකාරී වරහන්).


2
මට මෙම යෝජනාව එක් කිරීමට අවශ්‍ය වූ නමුත් වාසනාවකට මෙන් මම අඩු ශ්‍රේණිගත පිළිතුරු වෙත අනුචලනය කළෙමි. එය තව දුරටත් ඉහළ නංවනු ඇතැයි මම බලාපොරොත්තු වන අතර එය නියතයක සියලු ක්‍රියාකාරීත්වයන් ඇති බවත් එය ඉතා සරල හා සරල බවත් මම සම්පුර්ණයෙන්ම එකඟ වෙමි. සියළුම නවීන විසඳුම්වල බොයිලර් ප්ලේට් කේතයේ ප්‍රමාණය දෙස බලන විට වරහන් සාපේක්ෂව අනවශ්‍ය බව මට පෙනේ.
yaccob

1
මෙය සරළම පිළිතුරයි. එය සටහන් කළ යුතු වුවත් එයට යම්කිසි පොදු කාර්යයක් ඇති අතර ප්‍රතිලාභ අගය වෙනස් කිරීම මෝඩයන් නතර නොකරනු ඇත. එමඟින් කේතය තවදුරටත් ප්‍රභවය වෙනස් කිරීම
වළක්වනු ඇත

RMrMesees ප්‍රතිලාභ අගය වෙනස් කිරීම? ඔබ අදහස් කරන්නේ මූලාශ්‍රය සංස්කරණය කිරීමද? නමුත් මෙයින් ඔබ ආරක්ෂා වන්නේ C ++ තුළ නොවේ, නියතයන් (වැනි constexpr) සැබෑ දෘඩ නියතයන් වේ.
රුස්ලාන්

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

20

ඉහළ පිළිතුරු දෙකට අමතරව (UPPERCASE නම් සහිත විචල්‍යයන් භාවිතා කරන්න, නැතහොත් අගයන් කියවීමට පමණක් සෑදීම සඳහා ගුණාංග භාවිතා කරන්න), නම් කරන ලද නියතයන් ක්‍රියාත්මක කිරීම සඳහා මෙටාක්ලාස් භාවිතා කළ හැකි බව සඳහන් කිරීමට කැමැත්තෙමි . GitHub හි මෙටාක්ලාස් භාවිතා කරමින් මම ඉතා සරල විසඳුමක් ලබා දෙමි, ඒවායේ වර්ගය / නම පිළිබඳව අගයන් වඩාත් තොරතුරු දැන ගැනීමට ඔබට අවශ්‍ය නම් එය ප්‍රයෝජනවත් විය හැකිය:

>>> from named_constants import Constants
>>> class Colors(Constants):
...     black = 0
...     red = 1
...     white = 15
...
>>> c = Colors.black
>>> c == 0
True
>>> c
Colors.black
>>> c.name()
'black'
>>> Colors(0) is c
True

මෙය තරමක් දියුණු පයිතන්, නමුත් තවමත් භාවිතා කිරීමට ඉතා පහසු සහ පහසුය. (මොඩියුලයට නියත කියවීමට පමණක් ඇතුළුව තවත් විශේෂාංග කිහිපයක් ඇත, එහි README බලන්න.)

විවිධ නිධි වල පාවෙන සමාන විසඳුම් ඇත, නමුත් මගේ දැනුමට අනුව ඒවා නියතයන්ගෙන් (නියත වීම හෝ අත්තනෝමතික ආකාරයේ වීම වැනි) මා බලාපොරොත්තු වන මූලික අංගයන්ගෙන් එකක්වත් නොතිබුණි. ඒවා සාමාන්‍යයෙන් අඩු වශයෙන් අදාළ කරන්න. නමුත් YMMV, ප්‍රතිපෝෂණය සඳහා මම කෘත ful වෙමි. :-)


3
GitHub මත ක්‍රියාත්මක කිරීමට මම කැමතියි. ප්‍රතිලෝම බැලීමේ ක්‍රියාකාරිත්වය ක්‍රියාත්මක කරන මූලික පංතියක් ලිවීමට මම බොහෝ දුරට සූදානම්ව සිටියෙමි, නමුත් ඔබ එය කර ඇති බව මට පෙනේ!
කර්ර්

ස්තූතියි, er කර්, එය මට ලැබුණු පළමු ප්‍රතිපෝෂණයයි. :-)
hans_meine

නියමයි. මම මේක අත්හදා බැලුවා. මෙය විකල්පයක් ලෙස තිබීම සතුටක්. කියවීමට පමණක් ඇති අංගය ගැන මා සැලකිලිමත් වන්නේ දැයි තීරණය කර නැතත්, මෙය සරලව කරනවාට වඩා භාවිතා කිරීමට def enum(**enums): return type('Enum', (), enums). Numbers = enum(ONE=1, TWO=2, THREE='three'), අනුව stackoverflow.com/a/1695250/199364 , කොටස "කලින් අනුවාද වල ..."
ToolmakerSteve

19

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

class MyFinalProperty(object):

    @property
    def name(self):
        return "John"

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


වටිනා විසඳුමක් යටතේ. මම මෙම පිටුව සොයා ගැනීමෙන් පසුව මෙය ක්‍රියාත්මක කළෙමි (මෙම පිළිතුර නොවේ) සහ දැනටමත් නොමැති නම් එය එක් කිරීමට නැවත රවුම් විය. මෙම පිළිතුරේ ඇති ප්‍රයෝජනය අවධාරනය කිරීමට මට අවශ්‍ය විය.
මාක්

18

සංස්කරණය කරන්න: පයිතන් 3 සඳහා නියැදි කේතය එක් කරන ලදි

සටහන: මෙම අනෙක් පිළිතුර පෙනෙන්නේ එය පහත දැක්වෙන ආකාරයට වඩා සම්පූර්ණ ක්‍රියාවලියක් සපයන බවයි (වැඩි විශේෂාංග සහිතව).

පළමුව, මෙටාක්ලාස් එකක් සාදන්න :

class MetaConst(type):
    def __getattr__(cls, key):
        return cls[key]

    def __setattr__(cls, key, value):
        raise TypeError

මෙය සංඛ්‍යාන ගුණාංග වෙනස් වීම වළක්වයි. ඉන්පසු එම මෙටාක්ලාස් භාවිතා කරන වෙනත් පන්තියක් සාදන්න:

class Const(object):
    __metaclass__ = MetaConst

    def __getattr__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        raise TypeError

නැතහොත්, ඔබ පයිතන් 3 භාවිතා කරන්නේ නම්:

class Const(object, metaclass=MetaConst):
    def __getattr__(self, name):
        return self[name]

    def __setattr__(self, name, value):
        raise TypeError

මෙය උදාහරණ මුක්කු වෙනස් වීම වැළැක්විය යුතුය. එය භාවිතා කිරීමට, උරුම වන්න:

class MyConst(Const):
    A = 1
    B = 2

දැන් මුක්කු, කෙලින්ම හෝ නිදසුනක් හරහා ප්‍රවේශ විය යුතුය:

MyConst.A
# 1
my_const = MyConst()
my_const.A
# 1

MyConst.A = 'changed'
# TypeError
my_const.A = 'changed'
# TypeError

ඉහත ක්‍රියාවෙහි උදාහරණයක් මෙන්න . පයිතන් 3 සඳහා තවත් උදාහරණයක් මෙන්න .


10

ජාවාහි ස්ථිතික අවසාන විචල්‍යය (ජාවා "නියතය") හා සමානව ක්‍රියා කරන නියතයක් effectively ලදායී ලෙස නිර්මාණය කිරීම සඳහා ඔබට නම් කළ ටුපල් එකක් වැඩ කිරීමේ ක්‍රමයක් ලෙස භාවිතා කළ හැකිය. වැඩකරන විට, එය එක්තරා ආකාරයක අලංකාරයකි. (වඩාත් අලංකාර ප්‍රවේශයක් වනුයේ පයිතන් භාෂාව සරලව වැඩිදියුණු කිරීමයි --- ඔබට නැවත අර්ථ දැක්වීමට ඉඩ දෙන්නේ කුමන ආකාරයේ භාෂාවක්ද math.pi? - නමුත් මම කණගාටු වෙමි.)

. නම් කිරීමට ඔබට බල කරන ලෙස ටයිප් කරන්න.)

ඔබේ ආදර්ශය අනුගමනය කරමින්, ජාවාහි දී අපි යම් පන්තියක් තුළ නියතය අර්ථ දැක්විය යුතු බව ඔබට මතක ඇති ; ඔබ පන්තියේ නමක් සඳහන් නොකළ නිසා අපි එය අමතමු Foo. මෙන්න ජාවා පන්තිය:

public class Foo {
  public static final String CONST_NAME = "Name";
}

මෙන්න සමාන පයිතන්.

from collections import namedtuple
Foo = namedtuple('_Foo', 'CONST_NAME')('Name')

මට මෙහි එක් කිරීමට අවශ්‍ය ප්‍රධාන කරුණ නම් ඔබට වෙනම Fooවර්ගයක් අවශ්‍ය නොවීමයි (“නිර්නාමික නමක් සහිත ටුපල්” එකක් ඔක්සිමොරොන් _Fooමෙන් පෙනුනත් හොඳයි ), එබැවින් අපි අපේ නම් තැබීම නම් කරමු. මොඩියුල ආයාත කිරීමට පැන යන්න.

මෙහි දෙවන කරුණ නම්, අපි වහාම නාම පුවරුවේ නිදසුනක් නිර්මාණය කර එය කැඳවීම Foo; මෙය වෙනම පියවරකින් කිරීමට අවශ්‍ය නැත (ඔබට අවශ්‍ය නම් මිස). දැන් ඔබට ජාවා හි කළ හැකි දේ කළ හැකිය:

>>> Foo.CONST_NAME
'Name'

නමුත් ඔබට එයට අනුයුක්ත කළ නොහැක:

>>> Foo.CONST_NAME = 'bar'

AttributeError: can't set attribute

පිළිගැනීම: මම නම් කරන ලද ප්‍රවේශය සොයාගත්තා යැයි සිතුවෙමි, නමුත් පසුව වෙනත් අයෙකු සමාන (අඩු සංයුක්ත වුවද) පිළිතුරක් ලබා දුන් බව මට පෙනේ. පයිතන්හි "නම් කරන ලද ටුපල්ස්" යනු කුමක්දැයි මම දුටුවෙමි. , එය sys.version_infoදැන් නම් කරන ලද ටුපල් එකක් බව පෙන්වා දෙයි, එබැවින් සමහර විට පයිතන් සම්මත පුස්තකාලය දැනටමත් මෙම අදහස ඉදිරිපත් කර ඇත.

අවාසනාවට (මෙය තවමත් පයිතන් වීම), ඔබට සම්පූර්ණ Fooපැවරුම මුළුමනින්ම මකා දැමිය හැකි බව සලකන්න :

>>> Foo = 'bar'

(ෆේස්පෑම්)

නමුත් අවම වශයෙන් අපි Foo.CONST_NAMEවටිනාකම වෙනස් වීම වළක්වන අතර එය කිසි දෙයකට වඩා හොඳ නැත. වාසනාව.


නම් කරන ලද ප්‍රවේශය ගෙන ඒමට ස්තූතියි. නිසැකවම නවෝත්පාදනය. මගේ "අදහස් දැක්වීම" ඔබට අදාළ යැයි සිතිය හැකිය .
RayLuo

10

PEP 591 හි 'අවසාන' සුදුසුකම් ඇත. බලාත්මක කිරීම වර්ග පරීක්ෂකයාට පහළින් ඇත.

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

MY_CONSTANT: Final = 12407

සටහන: Final යතුරුපදය අදාළ වන්නේ පයිතන් 3.8 අනුවාදය සඳහා පමණි


9

මෙන්න "නියත" පන්තියක් ක්‍රියාත්මක කිරීමකි, එය කියවීමට පමණි (නියත) ගුණාංග සහිත අවස්ථා නිර්මාණය කරයි. උදා: භාවිතා කළ හැකි Nums.PIලෙස ආරම්භනය කර ඇති බව අගය ලබා ගැනීමට 3.14159, සහ Nums.PI = 22ව්යතිරේකයක් මතු කරයි.

# ---------- Constants.py ----------
class Constants(object):
    """
    Create objects with read-only (constant) attributes.
    Example:
        Nums = Constants(ONE=1, PI=3.14159, DefaultWidth=100.0)
        print 10 + Nums.PI
        print '----- Following line is deliberate ValueError -----'
        Nums.PI = 22
    """

    def __init__(self, *args, **kwargs):
        self._d = dict(*args, **kwargs)

    def __iter__(self):
        return iter(self._d)

    def __len__(self):
        return len(self._d)

    # NOTE: This is only called if self lacks the attribute.
    # So it does not interfere with get of 'self._d', etc.
    def __getattr__(self, name):
        return self._d[name]

    # ASSUMES '_..' attribute is OK to set. Need this to initialize 'self._d', etc.
    #If use as keys, they won't be constant.
    def __setattr__(self, name, value):
        if (name[0] == '_'):
            super(Constants, self).__setattr__(name, value)
        else:
            raise ValueError("setattr while locked", self)

if (__name__ == "__main__"):
    # Usage example.
    Nums = Constants(ONE=1, PI=3.14159, DefaultWidth=100.0)
    print 10 + Nums.PI
    print '----- Following line is deliberate ValueError -----'
    Nums.PI = 22

ආරම්භක ස්ථානයක් ලෙස මා භාවිතා කළ ike මයික් ග්‍රැහැම්ගේ ෆ්‍රොසෙන්ඩික්ට් වලට ස්තූතියි . වෙනස් කර ඇත, එබැවින් Nums['ONE']භාවිත සින්ටැක්ස් වෙනුවට Nums.ONE.

__ රවුෆියෝගේ පිළිතුරට ස්තූතියි, __ setattr __ ඉක්මවා යාමේ අදහස සඳහා.

නැතහොත් වැඩි ක්‍රියාකාරීත්වයක් සහිත ක්‍රියාත්මක කිරීමක් සඳහා, GitHub හි ansHans_meine ගේ නම්_කොන්ස්ටන්ට්ස් බලන්න


2
පයිතන් යනු වැඩිහිටියන්ගේ කැමැත්ත ප්‍රකාශ කරන භාෂාවකි. මේ වගේ දෙයකට ආරක්ෂාවක් නැහැ. Nums._d['PI'] = 22 දේවල් විකෘති නොවන ඒවා ලෙස සලකුණු කිරීමට භාෂාවම ක්‍රමයක් සපයන්නේ නැත, මම විශ්වාස කරමි.
අජේ එම්

8

ටුපල් එකක් නියතයක් ලෙස සුදුසුකම් ලබයි, මන්දයත් ඔබ එහි එක් අගයක් වෙනස් කිරීමට උත්සාහ කළහොත් ටියුපල් දෝෂයක් මතු කරයි. ඔබට එක් අගයක් සහිත ටුපල් එකක් ප්‍රකාශ කිරීමට අවශ්‍ය නම්, කොමාව එහි එකම වටිනාකමට පසුව තබන්න:

my_tuple = (0 """Or any other value""",)

මෙම විචල්‍යයේ අගය පරීක්ෂා කිරීමට, මේ හා සමාන දෙයක් භාවිතා කරන්න:

if my_tuple[0] == 0:
    #Code goes here

ඔබ මෙම අගය වෙනස් කිරීමට උත්සාහ කරන්නේ නම්, දෝෂයක් මතු වේ.


7

මම __setattr__මූලික වස්තු පන්තියේ ක්‍රමවේදය ඉක්මවා පන්තියක් සාදා මගේ නියතයන් ඒ සමඟ ඔතා, මම පයිතන් 2.7 භාවිතා කරන බව සලකන්න:

class const(object):
    def __init__(self, val):
        super(const, self).__setattr__("value", val)
    def __setattr__(self, name, val):
        raise ValueError("Trying to change a constant value", self)

නූලක් ඔතා ගැනීමට:

>>> constObj = const("Try to change me")
>>> constObj.value
'Try to change me'
>>> constObj.value = "Changed"
Traceback (most recent call last):
   ...
ValueError: Trying to change a constant value
>>> constObj2 = const(" or not")
>>> mutableObj = constObj.value + constObj2.value
>>> mutableObj #just a string
'Try to change me or not'

එය ඉතා සරල ය, නමුත් ඔබට නියත නොවන වස්තුවක් (constObj.value භාවිතා නොකර) මෙන් ඔබේ නියතයන් භාවිතා කිරීමට අවශ්‍ය නම්, එය තව ටිකක් තීව්‍ර වනු ඇත. මෙය ගැටළු ඇති කිරීමට ඉඩ ඇත, එබැවින් .valueඔබ නියතයන් සමඟ මෙහෙයුම් සිදු කරන බව පෙන්වීමට සහ දැන ගැනීමට තබා ගැනීම වඩාත් සුදුසුය (සමහර විට වඩාත්ම 'පයිතොනික්' ක්‍රමය නොවිය හැක).


සිත්ගන්නා ප්‍රවේශය සඳහා +1. ඒ වන විටත් ලබා දී ඇති පිළිතුරු තරම් පිරිසිදු නැත. මෙම පිළිතුරට වඩා සරලම කලින් යෝජනා කළ විසඳුම පවා def ONE(): return 1භාවිතා කිරීම පහසුය . ONE()ONE.value
මෙවලම් සාදන්නා

7

අවාසනාවට, පයිතන්ට තවමත් නියතයන් නොමැති අතර එය ලැජ්ජාවකි. ES6 දැනටමත් ජාවාස්ක්‍රිප්ට් ( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/const ) සඳහා ආධාරක නියතයන් එකතු කර ඇති බැවින් එය ඕනෑම ක්‍රමලේඛන භාෂාවක ඉතා ප්‍රයෝජනවත් දෙයකි. පයිතන් ප්‍රජාවේ වෙනත් පිළිතුරු වල පිළිතුරු ලෙස සම්මුතිය භාවිතා කරන්න - පරිශීලක ලොකු විචල්‍යය නියත ලෙස භාවිතා කරයි, නමුත් එය කේතයේ අත්තනෝමතික දෝෂ වලින් ආරක්ෂා නොවේ. ඔබ කැමති නම්, ඊළඟට ඔබට තනි ගොනු විසඳුමක් ප්‍රයෝජනවත් වනු ඇත (ලේඛනාගාරය එය භාවිතා කරන ආකාරය බලන්න).

file constants.py

import collections


__all__ = ('const', )


class Constant(object):
    """
    Implementation strict constants in Python 3.

    A constant can be set up, but can not be changed or deleted.
    Value of constant may any immutable type, as well as list or set.
    Besides if value of a constant is list or set, it will be converted in an immutable type as next:
        list -> tuple
        set -> frozenset
    Dict as value of a constant has no support.

    >>> const = Constant()
    >>> del const.temp
    Traceback (most recent call last):
    NameError: name 'temp' is not defined
    >>> const.temp = 1
    >>> const.temp = 88
    Traceback (most recent call last):
        ...
    TypeError: Constanst can not be changed
    >>> del const.temp
    Traceback (most recent call last):
        ...
    TypeError: Constanst can not be deleted
    >>> const.I = ['a', 1, 1.2]
    >>> print(const.I)
    ('a', 1, 1.2)
    >>> const.F = {1.2}
    >>> print(const.F)
    frozenset([1.2])
    >>> const.D = dict()
    Traceback (most recent call last):
        ...
    TypeError: dict can not be used as constant
    >>> del const.UNDEFINED
    Traceback (most recent call last):
        ...
    NameError: name 'UNDEFINED' is not defined
    >>> const()
    {'I': ('a', 1, 1.2), 'temp': 1, 'F': frozenset([1.2])}
    """

    def __setattr__(self, name, value):
        """Declaration a constant with value. If mutable - it will be converted to immutable, if possible.
        If the constant already exists, then made prevent againt change it."""

        if name in self.__dict__:
            raise TypeError('Constanst can not be changed')

        if not isinstance(value, collections.Hashable):
            if isinstance(value, list):
                value = tuple(value)
            elif isinstance(value, set):
                value = frozenset(value)
            elif isinstance(value, dict):
                raise TypeError('dict can not be used as constant')
            else:
                raise ValueError('Muttable or custom type is not supported')
        self.__dict__[name] = value

    def __delattr__(self, name):
        """Deny against deleting a declared constant."""

        if name in self.__dict__:
            raise TypeError('Constanst can not be deleted')
        raise NameError("name '%s' is not defined" % name)

    def __call__(self):
        """Return all constans."""

        return self.__dict__


const = Constant()


if __name__ == '__main__':
    import doctest
    doctest.testmod()

මෙය ප්‍රමාණවත් නොවේ නම්, ඒ සඳහා සම්පූර්ණ ටෙස්ට්කේස් බලන්න.

import decimal
import uuid
import datetime
import unittest

from ..constants import Constant


class TestConstant(unittest.TestCase):
    """
    Test for implementation constants in the Python
    """

    def setUp(self):

        self.const = Constant()

    def tearDown(self):

        del self.const

    def test_create_constant_with_different_variants_of_name(self):

        self.const.CONSTANT = 1
        self.assertEqual(self.const.CONSTANT, 1)
        self.const.Constant = 2
        self.assertEqual(self.const.Constant, 2)
        self.const.ConStAnT = 3
        self.assertEqual(self.const.ConStAnT, 3)
        self.const.constant = 4
        self.assertEqual(self.const.constant, 4)
        self.const.co_ns_ta_nt = 5
        self.assertEqual(self.const.co_ns_ta_nt, 5)
        self.const.constant1111 = 6
        self.assertEqual(self.const.constant1111, 6)

    def test_create_and_change_integer_constant(self):

        self.const.INT = 1234
        self.assertEqual(self.const.INT, 1234)
        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.INT = .211

    def test_create_and_change_float_constant(self):

        self.const.FLOAT = .1234
        self.assertEqual(self.const.FLOAT, .1234)
        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.FLOAT = .211

    def test_create_and_change_list_constant_but_saved_as_tuple(self):

        self.const.LIST = [1, .2, None, True, datetime.date.today(), [], {}]
        self.assertEqual(self.const.LIST, (1, .2, None, True, datetime.date.today(), [], {}))

        self.assertTrue(isinstance(self.const.LIST, tuple))

        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.LIST = .211

    def test_create_and_change_none_constant(self):

        self.const.NONE = None
        self.assertEqual(self.const.NONE, None)
        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.NONE = .211

    def test_create_and_change_boolean_constant(self):

        self.const.BOOLEAN = True
        self.assertEqual(self.const.BOOLEAN, True)
        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.BOOLEAN = False

    def test_create_and_change_string_constant(self):

        self.const.STRING = "Text"
        self.assertEqual(self.const.STRING, "Text")

        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.STRING += '...'

        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.STRING = 'TEst1'

    def test_create_dict_constant(self):

        with self.assertRaisesRegexp(TypeError, 'dict can not be used as constant'):
            self.const.DICT = {}

    def test_create_and_change_tuple_constant(self):

        self.const.TUPLE = (1, .2, None, True, datetime.date.today(), [], {})
        self.assertEqual(self.const.TUPLE, (1, .2, None, True, datetime.date.today(), [], {}))

        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.TUPLE = 'TEst1'

    def test_create_and_change_set_constant(self):

        self.const.SET = {1, .2, None, True, datetime.date.today()}
        self.assertEqual(self.const.SET, {1, .2, None, True, datetime.date.today()})

        self.assertTrue(isinstance(self.const.SET, frozenset))

        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.SET = 3212

    def test_create_and_change_frozenset_constant(self):

        self.const.FROZENSET = frozenset({1, .2, None, True, datetime.date.today()})
        self.assertEqual(self.const.FROZENSET, frozenset({1, .2, None, True, datetime.date.today()}))

        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.FROZENSET = True

    def test_create_and_change_date_constant(self):

        self.const.DATE = datetime.date(1111, 11, 11)
        self.assertEqual(self.const.DATE, datetime.date(1111, 11, 11))

        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.DATE = True

    def test_create_and_change_datetime_constant(self):

        self.const.DATETIME = datetime.datetime(2000, 10, 10, 10, 10)
        self.assertEqual(self.const.DATETIME, datetime.datetime(2000, 10, 10, 10, 10))

        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.DATETIME = None

    def test_create_and_change_decimal_constant(self):

        self.const.DECIMAL = decimal.Decimal(13123.12312312321)
        self.assertEqual(self.const.DECIMAL, decimal.Decimal(13123.12312312321))

        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.DECIMAL = None

    def test_create_and_change_timedelta_constant(self):

        self.const.TIMEDELTA = datetime.timedelta(days=45)
        self.assertEqual(self.const.TIMEDELTA, datetime.timedelta(days=45))

        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.TIMEDELTA = 1

    def test_create_and_change_uuid_constant(self):

        value = uuid.uuid4()
        self.const.UUID = value
        self.assertEqual(self.const.UUID, value)

        with self.assertRaisesRegexp(TypeError, 'Constanst can not be changed'):
            self.const.UUID = []

    def test_try_delete_defined_const(self):

        self.const.VERSION = '0.0.1'
        with self.assertRaisesRegexp(TypeError, 'Constanst can not be deleted'):
            del self.const.VERSION

    def test_try_delete_undefined_const(self):

        with self.assertRaisesRegexp(NameError, "name 'UNDEFINED' is not defined"):
            del self.const.UNDEFINED

    def test_get_all_defined_constants(self):

        self.assertDictEqual(self.const(), {})

        self.const.A = 1
        self.assertDictEqual(self.const(), {'A': 1})

        self.const.B = "Text"
        self.assertDictEqual(self.const(), {'A': 1, 'B': "Text"})

වාසි: 1. සම්පූර්ණ ව්‍යාපෘතිය සඳහා සියලුම නියතයන්ට ප්‍රවේශ වීම 2. නියතයන්ගේ අගයන් සඳහා දැඩි පාලනය

අඩුපාඩු: 1. අභිරුචි වර්ග සහ 'ඩික්ට්' වර්ගය සඳහා සහය නොදක්වයි

සටහන්:

  1. Python3.4 සහ Python3.5 සමඟ පරීක්ෂා කර ඇත (මම ඒ සඳහා 'tox' භාවිතා කරමි)

  2. පරීක්ෂණ පරිසරය:

.

$ uname -a
Linux wlysenko-Aspire 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

ශබ්ද කෝෂ ස්වයංක්‍රීයව නම් කරන ලද ටුපල් බවට පරිවර්තනය කිරීමෙන් ඔබට මෙය තරමක් දියුණු කළ හැකිය
පීටර් ෂෝර්න්

6

"නියතයන්" ප්‍රකාශ කිරීමේ පයිතොනික් ක්‍රමය මූලික වශයෙන් මොඩියුල මට්ටමේ විචල්‍යයකි:

RED = 1
GREEN = 2
BLUE = 3

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

ඇත්ත වශයෙන්ම, ඔබ පැහැදිලිවම සකසා ඇත්නම් මිස RED = 2.


22
ඔව්, නමුත් "පැහැදිලිව සැකසීමේ " හැකියාව අවහිරRED = 2 කිරීම යනු විචල්‍ය නාමයක් "නියත" ලෙස ප්‍රකාශ කිරීමට හැකිවීම (වෙනත් භාෂාවලින්) සම්පූර්ණ ප්‍රතිලාභයයි!
මෙවලම් සාදන්නා ස්ටීව්

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

E කෙවින්: " ඔබට ප්‍රතිලාභයක් ලැබේද ... ", staticපංතියක සියලුම අවස්ථාවන් සඳහා වටිනාකම සඳහා තනි ගබඩාවක් තිබීමේ වාසිය ? ඇත්ත වශයෙන්ම ස්ථිතික / පන්ති විචල්‍යයක් ප්‍රකාශ කිරීමේ හැකියාවක් නොමැති නම්.
මිනිත්තු

8
මූලික ගැටළුව නම්, සමහරු එය සත්‍යයේ ප්‍රභවයක්, වෙනස් කළ නොහැකි අගයක් ලෙස දැකීම සහ මැජික් අගයන් හඳුන්වා දීම වෙනුවට ඔවුන්ගේ කේතය පුරා සත්‍යයේ ප්‍රභවය ලෙස භාවිතා කිරීමයි (මම පයිතන්හි බොහෝ දේ දකිමි) - සහ වෙනත් අය එය කැමැත්තෙන් වෙනස් කිරීමට ඉඩ දී ඇති දෙයක් ලෙස දකිනු ඇත. යමෙකු ගෝලීය විචල්‍යයක් වෙනස් කළ විට, එය වෙනස් වූයේ කොහෙන්දැයි ඔබට කිව නොහැකි අතර, යෙදුම බිඳ වැටෙන්නේ “රතු” වෙනුවට RED = “නිල්” නිසා, ඔබ හඳුන්වා දෙන්නේ මුළුමනින්ම අනවශ්‍ය ගැටළුවක් වන අතර එය දැනටමත් සරලව විසඳා ඇත. විශ්වීය ලෙස වටහාගෙන ඇත.
Dagrooms

5

අපට විස්තර කිරීමේ වස්තුවක් නිර්මාණය කළ හැකිය.

class Constant:
  def __init__(self,value=None):
    self.value = value
  def __get__(self,instance,owner):
    return self.value
  def __set__(self,instance,value):
    raise ValueError("You can't change a constant")

1) අපට නිදර්ශන මට්ටමින් නියතයන් සමඟ වැඩ කිරීමට අවශ්‍ය නම්:

class A:
  NULL = Constant()
  NUM = Constant(0xFF)

class B:
  NAME = Constant('bar')
  LISTA = Constant([0,1,'INFINITY'])

>>> obj=A()
>>> print(obj.NUM)  #=> 255
>>> obj.NUM =100

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: You can't change a constant

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

# metaclass of my class Foo
class FooMeta(type): pass

# class Foo
class Foo(metaclass=FooMeta): pass

# I create constants in my metaclass
FooMeta.NUM = Constant(0xff)
FooMeta.NAME = Constant('FOO')

>>> Foo.NUM   #=> 255
>>> Foo.NAME  #=> 'FOO'
>>> Foo.NUM = 0 #=> ValueError: You can't change a constant

මම Foo හි උප පංතියක් නිර්මාණය කරන්නේ නම්, මෙම පන්තිය නියතය වෙනස් කිරීමට හැකියාවක් නොමැතිව උරුම වේ

class Bar(Foo): pass

>>> Bar.NUM  #=> 255
>>> Bar.NUM = 0  #=> ValueError: You can't change a constant

4

පයිතන් ශබ්දකෝෂ විකෘති වන බැවින් ඒවා නියතයන් ප්‍රකාශ කිරීමට හොඳ ක්‍රමයක් ලෙස නොපෙනේ:

>>> constants = {"foo":1, "bar":2}
>>> print constants
{'foo': 1, 'bar': 2}
>>> constants["bar"] = 3
>>> print constants
{'foo': 1, 'bar': 3}

4

ඔබට නියතයන් අවශ්‍ය නම් සහ ඒවායේ අගයන් නොසලකන්නේ නම් මෙන්න උපක්‍රමයක්:

හිස් පන්ති නිර්වචනය කරන්න.

උදා:

class RED: 
    pass
class BLUE: 
    pass

4

පයිතන්හි, නියතයක් යනු හුදෙක් සියලු අගනගරවල නමක් සහිත විචල්‍යයක් වන අතර, වචන අවධාරනය කරන්නේ අක්ෂරයෙන් ය,

උදා

DAYS_IN_WEEK = 7

ඔබට එය වෙනස් කළ හැකි පරිදි අගය විකෘති වේ. නමුත් නම සඳහා වන නීති රීති අනුව ඔබට නියතයක් යැයි කියනු ලැබේ, ඇයි ඔබ එසේ කරන්නේ? මම කිව්වේ, එය ඔබේ වැඩසටහනයි!

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

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

වටිනාකමට වෙනසක් යෙදීම අර්ථවත් වන සමහර ඒකක පරීක්ෂණයක් තිබේද? සැබෑ ලෝකයේ වුවද සතියේ දින ගණන වෙනස් කළ නොහැකි වුවද දින 8 ක සතියක් සඳහා කුමක් සිදුවේ දැයි බැලීමට. මෙම නීතිය පමණක් බිඳ දැමිය යුතු නම් භාෂාව ඔබ ව්‍යතිරේකයක් කිරීම නැවැත්වූයේ නම් ... ඔබට එය නියතයක් ලෙස ප්‍රකාශ කිරීම නැවැත්විය යුතුය, එය තවමත් යෙදුමේ නියතයක් වුවද, එය වෙනස් කළහොත් කුමක් සිදුවේ දැයි දකින මෙම එක් පරීක්ෂණ අවස්ථාවකි.

සියලුම ඉහළ අකුරු නාමය ඔබට පවසන්නේ එය නියතයක් වීමට අදහස් කරන බවයි. වැදගත් වන්නේ එයයි. කේතයට බාධා කිරීමට බල කරන භාෂාවක් නොවේ ඔබට කෙසේ හෝ වෙනස් කිරීමට බලය ඇත.

පයිතන්ගේ දර්ශනය එයයි.


4

මෙය කිරීමට පරිපූර්ණ ක්‍රමයක් නොමැත. මා තේරුම් ගත් පරිදි බොහෝ ක්‍රමලේඛකයින් හදුනාගැනීමේ ප්‍රාග්ධනය පමණක් භාවිතා කරයි, එබැවින් PI = 3.142 නියතයක් බව පහසුවෙන් වටහා ගත හැකිය.

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

def define(name, value):
  if (name + str(id(name))) not in globals():
    globals()[name + str(id(name))] = value

def constant(name):
  return globals()[name + str(id(name))]

define("PI",3.142)

print(constant("PI"))

මෙය PHP විලාසිතාවේ නියතයක් බවට පත්වන බව පෙනේ.

යථාර්ථයේ දී යමෙකුට වටිනාකම වෙනස් කිරීමට අවශ්‍ය වන්නේ මෙයයි:

globals()["PI"+str(id("PI"))] = 3.1415

ඔබ මෙහි සොයා ගන්නා අනෙක් සියලුම විසඳුම් සඳහා මෙය සමාන වේ - පංතියක් සාදා සැකසූ ගුණාංග ක්‍රමය නැවත අර්ථ දක්වන දක්ෂ අය පවා - ඔවුන් වටා සෑම විටම ක්‍රමයක් ඇත. පයිතන් යනු එයයි.

මගේ නිර්දේශය වන්නේ සියලු කරදර වළක්වා ඔබේ හඳුනාගැනීම් ප්‍රාග්ධනය කර ගැනීමයි. එය නියත නියතයක් නොවන නමුත් නැවත කිසිවක් සිදු නොවේ.


4

නම් කළ ටුපල් සමඟ මෙය කිරීමට පිරිසිදු ක්‍රමයක් තිබේ:

from collections import namedtuple


def make_consts(name, **kwargs):
    return namedtuple(name, kwargs.keys())(**kwargs)

භාවිත උදාහරණය

CONSTS = make_consts("baz1",
                     foo=1,
                     bar=2)

මෙම නිශ්චිත ප්‍රවේශය සමඟින් ඔබට ඔබේ නියතයන් නම් කළ හැකිය.


මෙය කියවන සෑම කෙනෙකුටම, කරුණාකර මතක තබා ගන්න, ඔබ විකෘති වස්තුවක් මෙම නියතයන්ගෙන් එකක් ලෙස සකසන්නේ නම්, ඕනෑම කෙනෙකුට එහි අභ්‍යන්තර වටිනාකම වෙනස් කළ හැකිය. උදාහරණයක් ලෙස, බාර් = [1, 2, 3] ට ඉඩ දෙන්න, එවිට ඔබට පහත පරිදි කළ හැකිය: CONSTS.bar [1] = 'a' සහ එය ප්‍රතික්ෂේප නොවනු ඇත. එබැවින් මේ ගැන සැලකිලිමත් වන්න.
ජුවාන් ඉග්නේෂියෝ සාන්චෙස්

විනෝදය සඳහා මා විසින් සාදන ලද මෙම අනවසර ක්‍රමය වෙනුවට, පයිතන්ගේ දේපල අලංකරණ යන්ත්‍රය භාවිතා කිරීම නිර්දේශ කරමි.
ජුවාන් ඉග්නේෂියෝ සාන්චෙස්

4

සමහර විට pconst පුස්තකාලය ඔබට උදව් වනු ඇත ( github ).

$ pip install pconst

from pconst import const
const.APPLE_PRICE = 100
const.APPLE_PRICE = 200

[Out] Constant value of "APPLE_PRICE" is not editable.


3

ඔබට StringVar හෝ IntVar යනාදිය භාවිතා කළ හැකිය, ඔබේ නියතය const_val වේ

val = 'Stackoverflow'
const_val = StringVar(val)
const.trace('w', reverse)

def reverse(*args):
    const_val.set(val)

2

ඔබට එය කළ හැක්කේ collections.namedtupleසහ itertools:

import collections
import itertools
def Constants(Name, *Args, **Kwargs):
  t = collections.namedtuple(Name, itertools.chain(Args, Kwargs.keys()))
  return t(*itertools.chain(Args, Kwargs.values()))

>>> myConstants = Constants('MyConstants', 'One', 'Two', Three = 'Four')
>>> print myConstants.One
One
>>> print myConstants.Two
Two
>>> print myConstants.Three
Four
>>> myConstants.One = 'Two'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

2

(මෙම ඡේදය එම පිළිතුරු මත අදහස් විය අදහස් කරන ලදී මෙතන හා එහි සඳහන් වන namedtupleනමුත්, එය බොහෝ කාලයක් අදහසක් බවට සුදුසු විය ලබා ඇත, එසේ, අහිංසකයෝ.)

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

ගණන් කරන ලද නියතයන් නම් කරන ලද ටුපල් සමඟ ක්‍රියාත්මක කළ හැකි නමුත් සරල පන්ති ප්‍රකාශයක් භාවිතා කිරීම සරල හා කාර්යක්ෂම වේ:

class Status:
    open, pending, closed = range(3)

වෙනත් වචන වලින් කිවහොත්, නිල ලියකියවිලි වර්ගය කියවීමට පමණක් හැසිරීම ඇත්ත වශයෙන්ම ක්‍රියාත්මක කරනවාට වඩා ප්‍රායෝගික ක්‍රමයක් භාවිතා කිරීමට කැමැත්තක් දක්වයි. මම හිතන්නේ එය පයිතන්හි සෙන්ගේ තවත් උදාහරණයක් බවට පත්වේ :

සරල දේට වඩා සංකීර්ණයි.

ප්‍රායෝගිකත්වය පාරිශුද්ධත්වයට පහර දෙයි.


2

මෙන්න එය දැනටමත් ලබා ගත හැකි පිළිතුරු සමහරක් වැඩිදියුණු කිරීමේ උත්සාහයක් ලෙස මා විසින් නිර්මාණය කරන ලද මුග්ධ එකතුවකි.

නියත භාවිතය පයිතොනික් නොවන බව මම දනිමි, ඔබ මෙය නිවසේදී නොකළ යුතුය!

කෙසේ වෙතත්, පයිතන් එවැනි ගතික භාෂාවක්! මෙම සංසදය පෙන්වන්නේ නියතයන් මෙන් පෙනෙන හා දැනෙන ඉදිකිරීම් නිර්මාණය කරන්නේ කෙසේද යන්නයි. භාෂාවෙන් ප්‍රකාශ කළ හැකි දේ ගවේෂණය කිරීමේ මූලික අරමුණ ලෙස මෙම පිළිතුර ඇත.

කරුණාකර මා සමඟ එතරම් රළු නොවන්න :-).

වැඩි විස්තර සඳහා මම මෙම මෝඩයන් ගැන සහායක බ්ලොග් අඩවියක් ලිවීමි .

මෙම ලිපියෙන් මම නියත විචල්‍යයක් අගයන් වෙත නිරන්තර යොමු කිරීමකට අමතන්නෙමි (වෙනස් කළ නොහැකි හෝ වෙනත් ආකාරයකින්). තවද, සේවාදායක කේතයකට එහි අගය (ය) යාවත්කාලීන කළ නොහැකි විකෘති වස්තුවක් සඳහන් කරන විට විචල්‍යයකට ශීත කළ අගයක් ඇති බව මම කියමි.

නියත අවකාශයක් (ස්පේස්කොන්ස්ටන්ට්ස්)

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

පයිතන්හි ස්ටැක් ඕවර් ප්‍රවාහයේ සහ බ්ලොග් පෝස්ට් එකක ප්‍රතිපත්ති මත පදනම් වූ මෝස්තරයක් ක්‍රියාත්මක කිරීමට පන්ති කර්මාන්තශාලාව භාවිතා කිරීම මම ගවේෂණය කළෙමි .

def SpaceConstants():
    def setattr(self, name, value):
        if hasattr(self, name):
            raise AttributeError(
                "Cannot reassign members"
            )
        self.__dict__[name] = value
    cls = type('SpaceConstants', (), {
        '__setattr__': setattr
    })
    return cls()

sc = SpaceConstants()

print(sc.x) # raise "AttributeError: 'SpaceConstants' object has no attribute 'x'"
sc.x = 2 # bind attribute x
print(sc.x) # print "2"
sc.x = 3 # raise "AttributeError: Cannot reassign members"
sc.y = {'name': 'y', 'value': 2} # bind attribute y
print(sc.y) # print "{'name': 'y', 'value': 2}"
sc.y['name'] = 'yprime' # mutable object can be changed
print(sc.y) # print "{'name': 'yprime', 'value': 2}"
sc.y = {} # raise "AttributeError: Cannot reassign members"

ශීත කළ අගයන් සහිත අවකාශයක් (SpaceFrozenValues)

මෙම මීළඟ මෝඩය යනු යොමු කරන ලද විකෘති වස්තූන් ශීත කළ අභ්‍යවකාශ කොන්ස්ටන්ට් වල වෙනස් කිරීමකි. මෙම ක්‍රියාවට නැංවීම, setattr සහ getattr කාර්යයන් අතර හවුල් වසා දැමීමක් ලෙස මා හඳුන්වන දේ ගසාකයි . මෙම mutable වස්තුව වටිනාකම විචල්ය විසින් පිටපත් කර එහි නමෙන්ම ඇත හැඹිලි වසා හවුල් උළෙල තුළ අර්ථ දක්වන්න. එය විකෘති වස්තුවක සංවෘත ආරක්ෂිත පිටපතක් ලෙස මා හඳුන්වන දේ සාදයි .

ගැඹුරු පිටපතක් කිරීමෙන් හැඹිලියේ වටිනාකම getattr විසින් ආපසු ලබා දෙන බැවින් ඔබ මෙම මෝඩකම භාවිතා කිරීමේදී ප්‍රවේශම් විය යුතුය . මෙම මෙහෙයුම විශාල වස්තූන් කෙරෙහි සැලකිය යුතු කාර්ය සාධන බලපෑමක් ඇති කළ හැකිය!

from copy import deepcopy

def SpaceFrozenValues():
    cache = {}
    def setattr(self, name, value):
        nonlocal cache
        if name in cache:
            raise AttributeError(
                "Cannot reassign members"
            )
        cache[name] = deepcopy(value)
    def getattr(self, name):
        nonlocal cache
        if name not in cache:
            raise AttributeError(
                "Object has no attribute '{}'".format(name)
            )
        return deepcopy(cache[name])
    cls = type('SpaceFrozenValues', (),{
        '__getattr__': getattr,
        '__setattr__': setattr
    })
    return cls()

fv = SpaceFrozenValues()
print(fv.x) # AttributeError: Object has no attribute 'x'
fv.x = 2 # bind attribute x
print(fv.x) # print "2"
fv.x = 3 # raise "AttributeError: Cannot reassign members"
fv.y = {'name': 'y', 'value': 2} # bind attribute y
print(fv.y) # print "{'name': 'y', 'value': 2}"
fv.y['name'] = 'yprime' # you can try to change mutable objects
print(fv.y) # print "{'name': 'y', 'value': 2}"
fv.y = {} # raise "AttributeError: Cannot reassign members"

නියත අවකාශයක් (ConstantSpace)

මෙම idiom යනු නියත විචල්‍යයන්ගේ හෝ ConstantSpace හි වෙනස් කළ නොහැකි නාම අවකාශයකි . එය පන්ති කර්මාන්ත ශාලාවක් සමඟ ස්ටොක් ඕවර් ප්‍රවාහයේ ඉතා සරල ජෝන් බෙට්ස්ගේ පිළිතුරේ එකතුවකි .

def ConstantSpace(**args):
    args['__slots__'] = ()
    cls = type('ConstantSpace', (), args)
    return cls()

cs = ConstantSpace(
    x = 2,
    y = {'name': 'y', 'value': 2}
)

print(cs.x) # print "2"
cs.x = 3 # raise "AttributeError: 'ConstantSpace' object attribute 'x' is read-only"
print(cs.y) # print "{'name': 'y', 'value': 2}"
cs.y['name'] = 'yprime' # mutable object can be changed
print(cs.y) # print "{'name': 'yprime', 'value': 2}"
cs.y = {} # raise "AttributeError: 'ConstantSpace' object attribute 'x' is read-only"
cs.z = 3 # raise "AttributeError: 'ConstantSpace' object has no attribute 'z'"

ශීත කළ අවකාශයක් (ශීත කළ අවකාශය)

මෙම මෝඩය ශීත කළ විචල්‍යයන්ගේ හෝ ශීත කළ අවකාශයේ වෙනස් කළ නොහැකි නාම අවකාශයකි . ජනනය කරන ලද ශීත කළ අවකාශ පන්තිය වසා දැමීමෙන් එක් එක් විචල්‍යය ආරක්ෂිත දේපලක් බවට පත් කිරීමෙන් එය පෙර රටාවෙන් ව්‍යුත්පන්න කර ඇත .

from copy import deepcopy

def FreezeProperty(value):
    cache = deepcopy(value)
    return property(
        lambda self: deepcopy(cache)
    )

def FrozenSpace(**args):
    args = {k: FreezeProperty(v) for k, v in args.items()}
    args['__slots__'] = ()
    cls = type('FrozenSpace', (), args)
    return cls()

fs = FrozenSpace(
    x = 2,
    y = {'name': 'y', 'value': 2}
)

print(fs.x) # print "2"
fs.x = 3 # raise "AttributeError: 'FrozenSpace' object attribute 'x' is read-only"
print(fs.y) # print "{'name': 'y', 'value': 2}"
fs.y['name'] = 'yprime' # try to change mutable object
print(fs.y) # print "{'name': 'y', 'value': 2}"
fs.y = {} # raise "AttributeError: 'FrozenSpace' object attribute 'x' is read-only"
fs.z = 3 # raise "AttributeError: 'FrozenSpace' object has no attribute 'z'"

2

පයිතන්හි, නියතයන් නොපවතින නමුත් විචල්‍යයක් නියතයක් බව ඔබට දැක්විය හැකි CONST_අතර විචල්‍ය නාමයේ ආරම්භයට එකතු කිරීමෙන් සහ එය විවරණයක නියතයක් බව සඳහන් කිරීමෙන් වෙනස් නොකළ යුතුය :

myVariable = 0
CONST_daysInWeek = 7    # This is a constant - do not change its value.   
CONSTANT_daysInMonth = 30 # This is also a constant - do not change this value.

විකල්පයක් ලෙස, ඔබට නියතයක් ලෙස ක්‍රියා කරන ශ්‍රිතයක් නිර්මාණය කළ හැකිය:

def CONST_daysInWeek():
    return 7;

1

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

මෙම පිළිතුර ක්‍රියාත්මක වන නමුත් බයිටරේ මූලද්‍රව්‍ය නැවත පැවරීමට උත්සාහ කිරීම දෝෂයක් මතු නොකරයි.

def const(func):
    '''implement const decorator'''
    def fset(self, val):
        '''attempting to set a const raises `ConstError`'''
        class ConstError(TypeError):
            '''special exception for const reassignment'''
            pass

        raise ConstError

    def fget(self):
        '''get a const'''
        return func()

    return property(fget, fset)


class Consts(object):
    '''contain all constants'''

    @const
    def C1():
        '''reassignment to C1 fails silently'''
        return bytearray.fromhex('deadbeef')

    @const
    def pi():
        '''is immutable'''
        return 3.141592653589793

නියතයන් වෙනස් කළ නොහැකි නමුත් නිරන්තර බයිටරේ පැවරුම නිහ ly ව අසමත් වේ:

>>> c = Consts()
>>> c.pi = 6.283185307179586  # (https://en.wikipedia.org/wiki/Tau_(2%CF%80))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "consts.py", line 9, in fset
    raise ConstError
__main__.ConstError
>>> c.C1[0] = 0
>>> c.C1[0]
222
>>> c.C1
bytearray(b'\xde\xad\xbe\xef')

වඩා බලවත්, සරල හා සමහර විට ඊටත් වඩා 'පයිතොනික්' ප්‍රවේශයකට මතක දර්ශන වස්තු භාවිතා කිරීම (<= python-2.6 හි ස්වාරක්ෂක වස්තු) ඇතුළත් වේ.

import sys

PY_VER = sys.version.split()[0].split('.')

if int(PY_VER[0]) == 2:
    if int(PY_VER[1]) < 6:
        raise NotImplementedError
    elif int(PY_VER[1]) == 6:
        memoryview = buffer

class ConstArray(object):
    '''represent a constant bytearray'''
    def __init__(self, init):
        '''
        create a hidden bytearray and expose a memoryview of that bytearray for
        read-only use
        '''
        if int(PY_VER[1]) == 6:
            self.__array = bytearray(init.decode('hex'))
        else:
            self.__array = bytearray.fromhex(init)

        self.array = memoryview(self.__array)

    def __str__(self):
        return str(self.__array)

    def __getitem__(self, *args, **kwargs):
       return self.array.__getitem__(*args, **kwargs)

ConstArray අයිතම පැවරුම TypeError:

>>> C1 = ConstArray('deadbeef')
>>> C1[0] = 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'ConstArray' object does not support item assignment
>>> C1[0]
222

1

මම python const සඳහා උපයෝගීතා ලිබ් එකක් ලියමි : kkconst - pypi support str, int, float, datetime

const ක්ෂේත්‍ර උදාහරණය එහි පාදක ආකාරයේ හැසිරීම පවත්වා ගනී.

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

from __future__ import print_function
from kkconst import (
    BaseConst,
    ConstFloatField,
)

class MathConst(BaseConst):
    PI = ConstFloatField(3.1415926, verbose_name=u"Pi")
    E = ConstFloatField(2.7182818284, verbose_name=u"mathematical constant")  # Euler's number"
    GOLDEN_RATIO = ConstFloatField(0.6180339887, verbose_name=u"Golden Ratio")

magic_num = MathConst.GOLDEN_RATIO
assert isinstance(magic_num, ConstFloatField)
assert isinstance(magic_num, float)

print(magic_num)  # 0.6180339887
print(magic_num.verbose_name)  # Golden Ratio

වැඩි විස්තර භාවිතය ඔබට pypi url: pypi හෝ github කියවිය හැකිය


1

ඔබට නියතයක් සංඛ්‍යාත්මක අරාවකින් ඔතා, එය ලිවීමට පමණක් සලකුණු කරන්න, සහ සෑම විටම එය දර්ශක ශුන්‍යයෙන් අමතන්න.

import numpy as np

# declare a constant
CONSTANT = 'hello'

# put constant in numpy and make read only
CONSTANT = np.array([CONSTANT])
CONSTANT.flags.writeable = False
# alternatively: CONSTANT.setflags(write=0)

# call our constant using 0 index    
print 'CONSTANT %s' % CONSTANT[0]

# attempt to modify our constant with try/except
new_value = 'goodbye'
try:
    CONSTANT[0] = new_value
except:
    print "cannot change CONSTANT to '%s' it's value '%s' is immutable" % (
        new_value, CONSTANT[0])

# attempt to modify our constant producing ValueError
CONSTANT[0] = new_value



>>>
CONSTANT hello
cannot change CONSTANT to 'goodbye' it's value 'hello' is immutable
Traceback (most recent call last):
  File "shuffle_test.py", line 15, in <module>
    CONSTANT[0] = new_value
ValueError: assignment destination is read-only

ඇත්ත වශයෙන්ම මෙය ආරක්ෂා කරන්නේ අංකිතයේ අන්තර්ගතය මිස විචල්ය "CONSTANT" නොවේ; ඔබට තවමත් කළ හැකිය:

CONSTANT = 'foo'

හා CONSTANTකෙසේ වෙතත් ඉක්මනින් ම TypeError පළමු වරට විසි කරන බව, වෙනස් කිරීමට ඉඩ ඇත CONSTANT[0]පසුව කේත රචනය තුල ලෙස හැඳින්වේ.

කෙසේ වෙතත් ... මම හිතන්නේ ඔබ යම් අවස්ථාවක එය වෙනස් කළා නම්

CONSTANT = [1,2,3]

දැන් ඔබට තවදුරටත් TypeError ලැබෙන්නේ නැත. හ්ම්ම්ම්ම් ....

https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.setflags.html

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.