python - मैं पायथन में स्थिर कैसे बना सकता हूं?
constants (19)
In Python, constants do not exist. But you can indicate that a variable is a constant and must not be changed by adding ' _CONSTANT ' to the start of the variable name, naming the variable in BLOCK CAPITALS, and adding a comment using the hashtag (' # ') eg :
normal_variable = 0
CONSTANT_variable = 1 # This is a constant - do not change its value!
क्या Python में निरंतर घोषित करने का कोई तरीका है? जावा में हम निरंतर मान इस तरीके से बना सकते हैं:
public static final String CONST_NAME = "Name";
पायथन में उपर्युक्त जावा निरंतर घोषणा के बराबर क्या है?
"स्थिरांक" घोषित करने का पाइथोनिक तरीका मूल रूप से एक मॉड्यूल स्तर चर है:
RED = 1
GREEN = 2
BLUE = 3
और फिर अपनी कक्षाएं या कार्य लिखें। चूंकि स्थिरांक लगभग हमेशा पूर्णांक होते हैं, और वे पाइथन में भी अपरिवर्तनीय होते हैं, आपके पास इसे बदलने का बहुत कम मौका होता है।
बेशक, अगर आप स्पष्ट रूप से RED = 2
सेट करते हैं।
आप एक निरंतर सरणी में निरंतर लपेट सकते हैं, इसे केवल लिखने के लिए ध्वजांकित करें, और हमेशा इसे इंडेक्स शून्य द्वारा कॉल करें।
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
of course this only protects the contents of the numpy, not the variable "CONSTANT" itself; you can still do:
CONSTANT = 'foo'
and CONSTANT
would change, however that would quickly throw an TypeError the first time CONSTANT[0]
is later called in the script.
although... I suppose if you at some point changed it to
CONSTANT = [1,2,3]
now you wouldn't get the TypeError anymore. hmmmm....
https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.setflags.html
आप एक स्थिरता को प्रभावी रूप से स्थिर बनाने के लिए एक वर्कअराउंड के रूप में उपयोग कर सकते हैं जो जावा में एक स्थिर अंतिम चर (जावा "स्थिर") के समान काम करता है। कामकाज के रूप में, यह सुरुचिपूर्ण तरह का है। (पाइथन भाषा को बेहतर बनाने के लिए एक और सुरुचिपूर्ण दृष्टिकोण --- --- किस प्रकार की भाषा आपको math.pi
फिर से परिभाषित करने देती है? - लेकिन मैं digress।)
(जैसा कि मैंने यह लिखा है, मुझे इस प्रश्न का एक और जवाब नामित किया गया है, लेकिन मैं यहां जारी रखूंगा क्योंकि मैं एक वाक्यविन्यास दिखाऊंगा जो जावा में आप अपेक्षा करते हैं कि अधिक बारीकी से समानता है, क्योंकि नाम बनाने की कोई आवश्यकता नहीं है नाम के रूप में टाइप करें जो आपको करने के लिए मजबूर करता है।)
आपके उदाहरण के बाद, आपको याद होगा कि जावा में हमें कुछ कक्षा के अंदर निरंतर परिभाषित करना होगा; क्योंकि आपने कक्षा के नाम का उल्लेख नहीं किया है, चलिए इसे 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
ताकि उम्मीद है कि यह जीता मॉड्यूल आयात करने के लिए बच नहीं है।
दूसरा बिंदु यह है कि हम तुरंत नामेटुपल का एक उदाहरण बनाते हैं, इसे Foo
; इसे एक अलग चरण में करने की आवश्यकता नहीं है (जब तक कि आप नहीं चाहते)। अब आप जावा में जो कर सकते हैं वह कर सकते हैं:
>>> Foo.CONST_NAME
'Name'
लेकिन आप इसे असाइन नहीं कर सकते हैं:
>>> Foo.CONST_NAME = 'bar'
…
AttributeError: can't set attribute
स्वीकृति: मैंने सोचा कि मैंने नामांकित दृष्टिकोण का आविष्कार किया है, लेकिन फिर मैं देखता हूं कि किसी और ने एक समान (हालांकि कम कॉम्पैक्ट) जवाब दिया है। फिर मैंने यह भी देखा कि पाइथन में "नामित टुपल्स" क्या हैं? , जो बताता है कि sys.version_info
अब एक sys.version_info
है, इसलिए शायद पाइथन मानक पुस्तकालय पहले से ही इस विचार के साथ आया था।
ध्यान दें कि दुर्भाग्यवश (यह अभी भी पायथन है), आप संपूर्ण Foo
असाइनमेंट को पूरी तरह मिटा सकते हैं:
>>> Foo = 'bar'
(Facepalm)
लेकिन कम से कम हम Foo.CONST_NAME
मान को बदलने से रोक रहे हैं, और यह कुछ भी नहीं है। सौभाग्य।
गुण स्थिरांक बनाने का एक तरीका है। आप इसे गेटर संपत्ति घोषित करके कर सकते हैं, लेकिन सेटटर को अनदेखा कर सकते हैं। उदाहरण के लिए:
class MyFinalProperty(object):
@property
def name(self):
return "John"
आप पाइथन गुणों का उपयोग करने के अधिक तरीके खोजने के लिए मैंने जो लेख लिखा है, उसे देख सकते हैं।
जैसा कि आप शायद पहले ही जानते हैं, पाइथन में स्थिरांक नहीं हैं :(
शायद सबसे आसान विकल्प इसके लिए एक समारोह को परिभाषित करना है। उदाहरण के लिए
def MY_CONSTANT():
return 42
MY_CONSTANT()
अब MY_CONSTANT()
की सभी कार्यक्षमता है (साथ ही कुछ कष्टप्रद ब्रेसिज़)।
दो शीर्ष उत्तरों के अलावा (केवल UPPERCASE नामों के साथ चर का उपयोग करें, या मानों को केवल पढ़ने के लिए गुणों का उपयोग करें), मैं उल्लेख करना चाहता हूं कि नामित स्थिरांक को लागू करने के लिए मेटाक्लास का उपयोग करना संभव है। मैं गिटहब में मेटाक्लास का उपयोग करके एक बहुत ही सरल समाधान प्रदान करता हूं जो उपयोगी हो सकता है यदि आप चाहते हैं कि मूल्य उनके प्रकार / नाम के बारे में अधिक जानकारीपूर्ण हों:
>>> 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
यह थोड़ा और अधिक उन्नत पायथन है, लेकिन अभी भी उपयोग करने में आसान और आसान है। (मॉड्यूल में कुछ और विशेषताएं हैं, जिनमें स्थिरांक केवल पढ़ने के लिए शामिल हैं, इसकी पढ़ाई देखें।)
विभिन्न भंडारों में चारों ओर तैरने वाले समान समाधान हैं, लेकिन मेरे सबसे अच्छे ज्ञान के लिए उनमें से किसी एक मौलिक विशेषताओं में से एक की कमी है जो मैं स्थिरांक (जैसे स्थिर, या मनमानी प्रकार के होने) से अपेक्षा करता हूं, या उनके पास गूढ़ विशेषताएं हैं उन्हें कम आम तौर पर लागू करें। लेकिन वाईएमएमवी, मैं प्रतिक्रिया के लिए आभारी होंगे। :-)
नहीं वहाँ नहीं है। आप पाइथन में निरंतर एक चर या मान घोषित नहीं कर सकते हैं। बस इसे मत बदलें।
यदि आप कक्षा में हैं, तो समकक्ष होगा:
class Foo(object):
CONST_NAME = "Name"
यदि नहीं, तो बस यह है
CONST_NAME = "Name"
लेकिन हो सकता है कि आप एलेक्स मार्टेलि द्वारा पायथन में कोड स्निपेट कॉन्स्टेंट्स को देखना चाहें।
भाषा को लागू करने के बजाय पायथन में, लोग नामकरण सम्मेलनों का उपयोग करते हैं जैसे निजी तरीकों के लिए _method
और संरक्षित तरीकों के लिए _method
का उपयोग _method
।
तो इसी तरह आप बस सभी कैप्स जैसे निरंतर घोषित कर सकते हैं
MY_CONSTANT = "one"
यदि आप चाहते हैं कि यह स्थिरता कभी भी बदली न हो, तो आप विशेषता पहुंच में जा सकते हैं और चाल चल सकते हैं, लेकिन एक आसान तरीका एक समारोह घोषित करना है
def MY_CONSTANT():
return "one"
केवल समस्या ही हर जगह है, आपको MY_CONSTANT () करना होगा, लेकिन फिर MY_CONSTANT = "one"
पायथन (आमतौर पर) में सही तरीका है।
आप स्थिरांक बनाने के लिए namedtuple का उपयोग भी कर सकते हैं:
>>> 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
मेरे मामले में, मुझे क्रिप्टो लाइब्रेरी के कार्यान्वयन के लिए अपरिवर्तनीय बाइट्रेरे की आवश्यकता थी जिसमें कई शाब्दिक संख्याएं थीं जिन्हें मैं सुनिश्चित करना चाहता था।
यह उत्तर काम करता है लेकिन bytearray तत्वों के पुन: असाइनमेंट का प्रयास एक त्रुटि नहीं उठाता है।
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
स्थिरांक अपरिवर्तनीय हैं, लेकिन लगातार बाइटरीरे असाइनमेंट चुपचाप विफल रहता है:
>>> 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
मैं पाइथन कॉन्स के लिए एक प्रयोग lib लिखता हूं: kkconst - pypi समर्थन str, int, float, datetime
कॉन्स फील्ड इंस्टेंस इसके मूल प्रकार के व्यवहार को बनाए रखेगा।
उदाहरण के लिए:
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
मैं शायद यहां एक चाल लापता हूं, लेकिन यह मेरे लिए काम करता प्रतीत होता है:
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__
विधि को __setattr__
वैरिएबल सेट करने के प्रयासों को किक करने और अवरुद्ध करने की अनुमति __setattr__
। यदि आप चाहते थे तो आप यहां एक अपवाद फेंक सकते हैं। कक्षा के नाम पर उदाहरण को इंस्टेंट करने से कक्षा के माध्यम से सीधे पहुंच को रोक दिया जाता है।
यह एक मूल्य के लिए कुल दर्द है, लेकिन आप अपने CONST
ऑब्जेक्ट पर बहुत कुछ संलग्न कर सकते हैं। ऊपरी वर्ग होने के कारण, कक्षा का नाम थोड़ा गड़बड़ भी लगता है, लेकिन मुझे लगता है कि यह कुल मिलाकर काफी संक्षिप्त है।
संपादित करें: पायथन 3 के लिए नमूना कोड जोड़ा गया
नोट: यह अन्य उत्तर ऐसा लगता है कि यह निम्नलिखित (अधिक सुविधाओं के साथ) के समान एक पूर्ण कार्यान्वयन प्रदान करता है।
सबसे पहले, metaclass बनाएं:
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
कार्रवाई में उपरोक्त Here's एक उदाहरण Here's गया है। पाइथन 3 के लिए Here's एक और उदाहरण दिया गया है।
Extending Raufio's answer, add a repr to return the value.
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)
def __repr__(self):
return ('{0}'.format(self.value))
dt = const(float(0.01))
print dt
then the object behaves a little more like you might expect, you can access it directly rather then '.value'
In python, a constant is simply a variable with a name in all capitals, with words separated by the underscore character,
जैसे
DAYS_IN_WEEK = 7
The value is mutable, as in you can change it. But given the rules for the name tell you is a constant, why would you? I mean, it is your program after all!
This is the approach taken throughout python. There is no private
keyword for the same reason. Prefix the name with an underscore and you know it is intended to be private. Code can break the rule....just as a programmer could remove the private keyword anyway.
Python could have added a const
keyword... but a programmer could remove keyword and then change the constant if they want to, but why do that? If you want to break the rule, you could change the rule anyway. But why bother to break the rule if the name makes the intention clear?
Maybe there is some unit test where it makes sense to apply a change to value? To see what happens for an 8 day week even though in the real world the number of days in the week cannot be changed. If the language stopped you making an exception if there is just this one case you need to break the rule...you would then have to stop declaring it as a constant, even though it still is a constant in the application, and there is just this one test case that sees what happens if it is changed.
सभी ऊपरी केस नाम आपको बताता है कि यह स्थिर होना है। यही महत्वपूर्ण है। कोड पर बाधाओं को मजबूर करने वाली कोई भाषा नहीं है, आपके पास वैसे भी बदलने की शक्ति है।
वह अजगर का दर्शन है।
We can create a descriptor object:
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")
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
You can use StringVar or IntVar, etc, your constant is const_val
val = ''
const_val = StringVar(val)
const.trace('w', reverse)
def reverse(*args):
const_val.set(val)
well.. even though this is outdated, let me add my 2 cents here :-)
class ConstDict(dict):
def __init__(self, *args, **kwargs):
super(ConstDict, self).__init__(*args, **kwargs)
def __setitem__(self, key, value):
if key in self:
raise ValueError("Value %s already exists" % (key))
super(ConstDict, self).__setitem__(key, value)
Instead of ValueError to break, you can prevent any update happening there. One advantage of this is that you can add constants dynamically in the program but you cannot change once a constant is set. Also you can add any rule or whatsoever before setting a constant(something like key must be a string or a lower case string or upper case string and so on before setting the key)
However, I do not see any importance of setting constants in Python. No optimizations can happen like in C and hence it is something that is not required, I guess.
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