পাইথনে আমি কীভাবে একটি ধ্রুবক তৈরি করব?


988

পাইথনে স্থির ঘোষণার কোনও উপায় আছে কি? জাভাতে আমরা এই পদ্ধতিতে ধ্রুবক মান তৈরি করতে পারি:

public static final String CONST_NAME = "Name";

পাইথনে উপরের জাভা ধ্রুবক ঘোষণার সমতুল্য কি?


6
অজগরটির সম্পত্তি ফাংশন / ডেকরেটারের মাধ্যমে কেবল পঠনযোগ্য কেবল পরিবর্তনশীলগুলি তৈরির উপায় । উত্তর এর INV যে একটি কাস্টম ব্যবহারের একটি উদাহরণ। সম্পত্তি তার থেকে বেশি সাধারণ-ব্যবহারযোগ্য, যদিও এটি কীভাবে কাজ করে তার একটি ভাল বিশ্লেষণ শালভ চতুর্বেদীর পাইথন বৈশিষ্ট্য এবং পদ্ধতিগুলির উপর
n611x007

20
আইএমএইচও, বল প্রয়োগের অবিচ্ছিন্নতা "পাইথোনিক নয়"। পাইথন ২.7 এ আপনি লিখতেও পারেন True=Falseএবং তারপরেও (2+2==4)==Trueফিরে আসতে পারেন False
osa

8
অন্যান্য উত্তরগুলি যেমন বোঝায় যে ধ্রুবকগুলি ঘোষণা করার কোনও উপায় বা প্রয়োজন নেই। তবে আপনি সম্মেলনগুলি সম্পর্কে এই পিইপি পড়তে পারেন । যেমন THIS_IS_A_CONSTANT
রসিকা পেরেরা

34
@ জোসা: আপনি অজগর 3 - এ এটি করতে পারবেন না SyntaxError: can't assign to keyword। এটি একটি ভাল জিনিস মনে হচ্ছে।
nnot101

3
অবাক করা অবধি এটি এখনও অবধি উল্লেখ করা হয়নি, তবে এনুমস গণনা করা ধ্রুবকগুলি সংজ্ঞায়িত করার ভাল উপায় বলে মনে হবে।
cs95

উত্তর:


973

কোন নেই. আপনি পাইথনে স্থির হিসাবে কোনও পরিবর্তনীয় বা মান ঘোষণা করতে পারবেন না। শুধু এটি পরিবর্তন করবেন না।

আপনি যদি একটি ক্লাসে থাকেন তবে সমমানেরটি হবে:

class Foo(object):
    CONST_NAME = "Name"

যদি না হয়, এটা ঠিক

CONST_NAME = "Name"

তবে আপনি অ্যালেক্স মার্তেলির পাইথনের কোড স্নিপেট কনস্ট্যান্টসটি একবার দেখতে চান ।


পাইথন ৩.৮ অনুসারে, একটি 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
তারপরে "পাইথনের কনস্ট্যান্টস" তে যা আছে তা করুন আপনার "সম্পত্তি" ফাংশন বা সজ্জাকারী ব্যবহার করা উচিত।
শেঠ জনসন

26
লোকেরা পার্লে একই বৈশিষ্ট্য সম্পর্কে জিজ্ঞাসা করে। "ব্যবহার ধ্রুবক" নামে একটি আমদানি মডিউল রয়েছে, তবে (এএফআইএকে) এটি একটি ক্ষুদ্র ফাংশন তৈরির জন্য কেবল একটি মোড়ক যা মানটি দেয়। পাইথনেও আমি একই কাজ করি। উদাহরণ:def MY_CONST_VALUE(): return 123
কেভিনারপে

8
"কোন নেই." সত্য, তবে অন্য লোকের কাজের উপর ভিত্তি করে আমি অজগর ২.7 এর "কনস্ট্যান্টস" এর একটি সংক্ষিপ্ত এবং সাধারণ প্রয়োগের সাথে (যার "এনাম" নেই) একটি উত্তর যুক্ত করেছি। এগুলি কেবলমাত্র পঠনযোগ্য-এর মতো এবং এগুলির name.attributeকোনও মান থাকতে পারে। ঘোষণা সহজ Nums = Constants(ONE=1, PI=3.14159, DefaultWidth=100.0), ব্যবহার সহজবোধ্য print 10 + Nums.PI, ব্যতিক্রম পরিবর্তন ফলাফলে প্রয়াস Nums.PI = 22=> ValueError (..)।
টুলমেকারস্টেভ

108
শুধু এটি পরিবর্তন করবেন না। আপনি আমার দিনটি তৈরি করেছেন
হাই-অ্যাঞ্জেল

89
"শুধু এটিকে পরিবর্তন করবেন না" মোটেই সহায়ক নয়। এটি প্রশ্নের উত্তর দেয় না এবং আমি এটি সরিয়ে দেওয়ার পরামর্শ দেব।
বারটেক বানাচিউইচজ

354

কোন ব্যাপার constসকল ভাষার মতো শব্দ, কিন্তু এটি একটি প্রপার্টি যে নির্মাণ করা সম্ভব একটি "সংগ্রহকারী ফাংশন" হয়েছে ডেটা পড়তে কিন্তু না "সেটার ফাংশন" ডেটা পুনরায় লিখতে। এটি মূলত সনাক্তকারীকে পরিবর্তন হওয়া থেকে রক্ষা করে।

এখানে শ্রেণীর সম্পত্তি ব্যবহার করে একটি বিকল্প বাস্তবায়ন:

নোট করুন যে পাঠকরা ধ্রুবকগুলির বিষয়ে ভাবছেন তার পক্ষে কোড সহজ নয়। নীচে ব্যাখ্যা দেখুন

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. সেটার ফাংশন একটি টাইপরর উত্থাপন করে যাতে এটি কেবল পঠনযোগ্য
  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

মনে রাখবেন যে @ অ্যাপ্লিকেশন সাজসজ্জাটি অবচিত বলে মনে হচ্ছে।

  1. সনাক্তকারী এফওওর সংজ্ঞা দেওয়ার জন্য, ফার্স দুটি ফাংশন সংজ্ঞায়িত করে (fset, fget - নামগুলি আমার পছন্দ অনুসারে)।
  2. তারপরে বিল্ট-ইন propertyফাংশনটি এমন কোনও অবজেক্টটি তৈরি করতে ব্যবহার করুন যা "সেট" বা "পেতে" হতে পারে।
  3. টীকা টুপি propertyফাংশন এর প্রথম দুটি পরামিতি নামকরণ করা হয় fsetএবং fget
  4. আসলে ব্যবহার করুন যে, আমরা আমাদের নিজস্ব সংগ্রহকারী ও সেটার জন্য এই অত্যন্ত নাম মনোনীত করেছিলেন এবং একটি শব্দ-অভিধান ** (ডাবল তারকাচিহ্ন) ব্যবহার করে তৈরি প্রয়োগ যে পরিধি স্থানীয় সংজ্ঞায় বেশ পরামিতি পাস propertyফাংশন

11
উপর ডকুমেন্টেশন উপর ভিত্তি করে AttributeErrorএবং TypeErrorআমি মনে করি উত্থাপিত ব্যতিক্রম একটি নতুন ত্রুটি, যা আমি নামকরণের প্রস্তাব হওয়া উচিত ConstantErrorবা ওই জাতীয় কিছু, যা একটি উপশ্রেণী হয় TypeError। দস্তাবেজের যে বিভাগটি আমাকে তা ভাবিয়ে
আর্টঅফ ওয়ারফেয়ার

3
আমি এই কোড দিয়ে অবাক। এফইও () এবং বার () পদ্ধতিগুলি ফন্টের যুক্তি হিসাবে কেন স্বতন্ত্র? আমার আইডিই রেখার উপর বন্ধনীগুলি আন্ডারলাইন করে ("সংকলন" ত্রুটি)। আমি এতে নিজেকে রাখতে ক্লান্ত হয়েছি কিন্তু তখন আমি একটি ত্রুটি পাই।
ব্যবহারকারী3770060

10
এই দৈর্ঘ্যের দিকে যাওয়া অজগর ভাষায় একটি স্পষ্ট ঘাটতির রূপরেখা দেয়। তারা এটিকে পাইথন 3 এ যুক্ত করার প্রয়োজনীয়তা কেন অনুভব করলো না? আমি বিশ্বাস করতে পারি না কেউই এর পরামর্শ দেয় এবং আমি কেবল কোনও কমিটির 'না, ধ্রুবকগুলির পিছনে যুক্তি দেখতে পাচ্ছি না? নাহ। '
অ্যান্ড্রু এস

8
এবং আপনার সমাধানটি এখনও একটি নির্ধারিত পাইথন প্রোগ্রামার দ্বারা এটি ব্যবহার করে সংশোধন করা যেতে পারেCONST.__dict__['FOO'] = 7
পিপ্পারি

11
@ অস্কারসমিত, আমি মনে করি এটি 'স্ব নথিভুক্ত কোড' ডিজাইনের উন্নতি করবে। যখন আমি কোডটিতে স্পষ্ট করে বলি যে কিছু মান পরিবর্তন করতে পারে না, তখন সমস্ত উত্স কোড পড়া এবং বুঝতে হবে যে কোনও মান কখনই পরিবর্তন হয় না than এছাড়াও, এটি কারওরূপে ভাল, ধ্রুবক হওয়া উচিত এমন একটি মান পরিবর্তন করার সম্ভাবনাটিকে বাধা দেয়। মনে রাখবেন: অন্তর্নিহিতের চেয়ে সুস্পষ্ট ভাল।
গ্যাব্রিয়েল

112

পাইথনে ভাষা প্রয়োগের পরিবর্তে লোকেরা নামকরণের সম্মেলনগুলি যেমন __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

17
করা def MY_CONSTANT(): return "one"কাউকে থামাবে না, পরে কোডে, করছে MY_CONSTANT = "two"(বা ফাংশনটি পুনরায় ঘোষণা করা)।
ম্যাথু শিনকেল

6
@ ম্যাথেজশিনচেল এটি কনভেনশন সম্পর্কে, এছাড়াও মাই_কন্ট্যান্ট পরিবর্তন করলে মাই_কন্ট্যান্ট () ব্যবহার পরিবর্তন হবে না তবে ত্রুটি ছুঁড়ে দেবে, এবং অজগরটিতে আপনি যদি কিছু পরিবর্তন করতে চান তবে কোনও চালাক কৌশল আপনাকে রক্ষা করতে পারে না।
অনুরাগ ইউনিয়াল

3
নামকরণকৃত পদ্ধতি গ্রহণের জন্য ধন্যবাদ অবশ্যই উদ্ভাবনী। আপনি এখানে আমার "মন্তব্য" প্রাসঙ্গিকও পেতে পারেন।
রায়লুও

@ ম্যাথেজশিংকেল আপনি অজগরটিতে যে কোনও কিছুই পুনরায় সংজ্ঞায়িত করতে পারেন, সুতরাং এটি সত্যিই খুব ভাল বিষয় নয়।
cslotty

@ ম্যাথেজশিংকেল এই ধারণাটি লেখার জন্য নয় MY_CONSTANT = MY_CONSTANT(), তবে MY_CONSTANT()ধ্রুবক হিসাবে ব্যবহার করার জন্য । অবশ্যই, এটি। তবে এটি ঠিক আছে এবং অজগর নীতিটির সাথে সামঞ্জস্যপূর্ণ "আমরা সকলেই এখানে প্রাপ্তবয়স্ক" - অর্থাত্ বিকাশকারীরা যখন কোনও উপযুক্ত কারণ থাকতে পারে এবং তারা কী করছেন তা জানতে পারে এমন কোনও নিয়মকে ওভাররাইড করার সিদ্ধান্ত নিতে খুব কমই নিষেধ করা হবে।
jonathan.scholbach

69

আমি সম্প্রতি এটিতে একটি খুব সংক্ষিপ্ত আপডেট পেয়েছি যা স্বয়ংক্রিয়ভাবে অর্থবহ ত্রুটি বার্তা উত্থাপন করে এবং এর মাধ্যমে অ্যাক্সেসকে বাধা দেয় __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
আমি মনে করি সাধারণত আপনি সেই পরিস্থিতিতে কিছু ধরণের সম্পর্কিত বান্ডিলগুলিতে গোষ্ঠী স্থাপন করতে চাইবেন (বরং একটি বিশাল কন্ট্রোল অবজেক্ট থাকুক), সুতরাং সম্ভবত এটি কোনও খারাপ জিনিস নয়।
জন বেটস্

এই উত্তর এখনও এত নিচে কেন ?! __slots__সমাধান তাই মার্জিত এবং কার্যকর। আমি যা পড়েছি তার কাছ থেকে এটি পাইথনের ধ্রুবক তৈরি করার মতোই কাছাকাছি। আপনাকে অনেক ধন্যবাদ. এবং আগ্রহী প্রত্যেকের জন্য, এখানে যাদুটির একটি উজ্জ্বল এবং গভীরতর ব্যাখ্যা __slots__
জনগ্যাল্ট

34

পাইথনের ধ্রুবক নেই।

সম্ভবত সবচেয়ে সহজ বিকল্প এটির জন্য একটি ফাংশন সংজ্ঞায়িত করা:

def MY_CONSTANT():
    return 42

MY_CONSTANT() এখন একটি ধ্রুবকের সমস্ত কার্যকারিতা রয়েছে (আরও কিছু বিরক্তিকর ধনুর্বন্ধনী)।


1
আমি কেবল এই পরামর্শটি যুক্ত করতে চেয়েছিলাম তবে ভাগ্যক্রমে আমি নিম্ন-রেটে দেওয়া উত্তরগুলিতে স্ক্রোল করেছি। আমি আশা করি এটি আরও উন্নত হবে এবং আমি সম্পূর্ণরূপে একমত যে এটিতে একটি ধ্রুবকের সমস্ত কার্যকারিতা রয়েছে এবং এটি খুব সহজ এবং সোজা। সমস্ত পরিশীলিত সমাধানগুলিতে বয়লারপ্লেট কোডের পরিমাণের দিকে তাকিয়ে আমি ধনুর্বন্ধনীগুলি তুলনামূলকভাবে অযাচিত পাই।
ইয়াকব

1
এটি সহজ সরল উত্তর, যদিও এটি লক্ষ্য করা উচিত এটির কিছুটা ওভারহেড রয়েছে এবং প্রত্যাবর্তনের মানটি সংশোধন করা ইডিয়ट्सকে থামিয়ে দেবে না। এটি কেবল কোডটি আরও উত্স পরিবর্তন করে রেখাকে নীচে রোধ করবে
মিস্টার মিিসিজ

@ এমআরমিসিজ ফেরত মান পরিবর্তন করছে? আপনি কি উত্সটি সম্পাদনা করতে চান? তবে এখান থেকে আপনি এমনকি সি ++ তেও সুরক্ষিত নন, যেখানে ধ্রুবকগুলি (যেমন constexpr) সত্যিকারের শক্ত ধ্রুবক।
রুসলান

@ রুসলান আমার অর্থ কি ছিল যে পাইথনের কোনও কনটেক্সট্রপ নেই তাই এটি বাহ্যিক প্রসঙ্গে ফিরে আসার পরে সম্পাদিত হওয়া মানটি থামবে না। এই উদাহরণে হিমশীতল রাষ্ট্র প্রয়োগ করতে 42 টির জন্য কিছুই করা হয়নি।
মিঃমিসিজ

20

দুটি শীর্ষ উত্তর ছাড়াও (কেবলমাত্র 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

এটি পাইথন কিছুটা উন্নত তবে এটি এখনও ব্যবহার করা সহজ এবং সহজ। (মডিউলটির আরও কিছু বৈশিষ্ট্য রয়েছে, ধ্রুবকগুলি কেবলমাত্র পঠনযোগ্য হয়, তার README দেখুন))

বিভিন্ন সংগ্রহস্থলগুলিতে প্রায় একই রকম সমাধানগুলি ভেসে উঠছে তবে আমার জ্ঞানের সেরা হিসাবে তাদের কাছে হয় ধ্রুবকদের কাছ থেকে আমি প্রত্যাশা করা মৌলিক বৈশিষ্ট্যগুলির একটির অভাব (যেমন ধ্রুবক হওয়া বা স্বেচ্ছাচারী ধরণের হওয়া), অথবা তাদের মজাদার বৈশিষ্ট্যগুলি যোগ করেছে যে এগুলিকে সাধারণভাবে প্রযোজ্য কম করুন। তবে ওয়াইএমএমভি, আমি প্রতিক্রিয়ার জন্য কৃতজ্ঞ হব। :-)


3
আমি গিটহাবে আপনার বাস্তবায়ন পছন্দ করি। আমি একটি বেসিক ক্লাস লিখতে প্রায় প্রস্তুত ছিল যা বিপরীত অনুসন্ধান কার্যকারিতা বাস্তবায়িত করেছিল, কিন্তু আমি দেখতে পাচ্ছি যে আপনি এটি এবং আরও কিছু করেছেন!
কেরার

ধন্যবাদ, @ কের, এটি আমার প্রথম প্রতিক্রিয়া এবং আমাকে খুশি করেছে। :-)
hans_meine

অসাধারণ. আমি এই চেষ্টা করেছিলাম। বিকল্প হিসাবে এটি পেয়ে ভাল লাগছে। যদিও আমি সিদ্ধান্ত নিইনি যে আমি কেবল পঠনযোগ্য দিক সম্পর্কে যথেষ্ট যত্ন নিই, কেবল এটি করার চেয়ে এটি ব্যবহার করার জন্য def enum(**enums): return type('Enum', (), enums)Numbers = enum(ONE=1, TWO=2, THREE='three'), স্ট্যাকওভারফ্লো.com / a / 1695250 / 199364 অনুসারে বিভাগ "পূর্ববর্তী সংস্করণগুলিতে ..."
টুলমেকারস্টেভ

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

আপনি জাভাতে স্থিতিশীল চূড়ান্ত চলকের (একইভাবে একটি জাভা "ধ্রুবক") এর মতো একইভাবে কাজ করে এমন একটি ধ্রুবক তৈরি করতে কার্যকরভাবে একটি নেয়ারটুপল ব্যবহার করতে পারেন। ওয়ার্কআরউন্ডস যেতে যেতে এটি একরকম মার্জিত। (পাইথন ভাষার সহজতর উন্নতি করার জন্য আরও মার্জিত দৃষ্টিভঙ্গি হ'ল --- কোন ধরণের ভাষা আপনাকে নতুন সংজ্ঞা দিতে দেয় 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'

(Facepalm)

তবে কমপক্ষে আমরা Foo.CONST_NAMEমানটি পরিবর্তন হতে বাধা দিচ্ছি , এবং এটি কোনও কিছুর চেয়ে ভাল। শুভকামনা।


নামকরণকৃত পদ্ধতি গ্রহণের জন্য ধন্যবাদ অবশ্যই উদ্ভাবনী। আপনি এখানে আমার "মন্তব্য" প্রাসঙ্গিকও পেতে পারেন।
রায়লুও

10

পিইপি 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

@ মাইকগ্রাহামের ফ্রোজেনডিক্টকে ধন্যবাদ , যা আমি একটি প্রাথমিক পয়েন্ট হিসাবে ব্যবহার করেছি। পরিবর্তিত হয়েছে, সুতরাং পরিবর্তনের পরিবর্তে Nums['ONE']ব্যবহারের সিনট্যাক্সটি Nums.ONE

এবং @ রউফিয়োর জবাবকে ধন্যবাদ, __ সেট্যাট্র __ কে ওভাররাইড করার জন্য আইডিয়াটির জন্য ধন্যবাদ

বা আরও কার্যকারিতা সহ একটি বাস্তবায়নের জন্য, গিটহাবে @ હંস_মাইনের নামযুক্ত_কন্ট্যান্টস দেখুন


2
পাইথন বড়দের সম্মতি দেওয়ার ভাষা language এর মতো কোনও কিছুর বিরুদ্ধে কোনও সুরক্ষা নেই। Nums._d['PI'] = 22 আমি বিশ্বাস করি যে ভাষা নিজেই জিনিসগুলিকে অ-পরিবর্তনীয় হিসাবে চিহ্নিত করার কোনও উপায় সরবরাহ করে না।
অজয় এম

8

একটি টিপল প্রযুক্তিগতভাবে একটি ধ্রুবক হিসাবে যোগ্যতা অর্জন করে, কারণ আপনি যদি এর মানগুলির মধ্যে একটি পরিবর্তন করার চেষ্টা করেন তবে একটি টিপল একটি ত্রুটি বাড়িয়ে তুলবে। আপনি যদি একটি মান সহ একটি টিপল ঘোষণা করতে চান তবে তার একমাত্র মানের পরে কমাটি রাখুন, এর মতো:

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

এই ভেরিয়েবলের মানটি পরীক্ষা করতে, এর অনুরূপ কিছু ব্যবহার করুন:

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

আপনি যদি এই মানটি পরিবর্তন করার চেষ্টা করেন তবে একটি ত্রুটি উত্থাপিত হবে।


7

আমি একটি ক্লাস তৈরি করব যা __setattr__বেস অবজেক্ট ক্লাসের পদ্ধতিটিকে ওভাররাইড করে এবং এটির সাথে আমার ধ্রুবকগুলিকে আবৃত করে রাখুন, নোট করুন যে আমি পাইথন ২.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'

এটি বেশ সহজ, তবে আপনি যদি নিজের ধ্রুবকগুলি একই ধরণের অবিচ্ছিন্ন অবজেক্ট (কনস্টোবিজ.ভ্যালু ব্যবহার না করে) ব্যবহার করতে চান তবে এটি কিছুটা আরও নিবিড় হবে। এটি সম্ভবত সমস্যার সৃষ্টি করতে পারে, তাই .valueআপনি ধ্রুবকগুলির সাথে অপারেশন করছেন (এটি সম্ভবত সবচেয়ে 'পাইথোনিক' উপায় নয়) এবং এটি জেনে রাখা ভাল ।


আকর্ষণীয় পদ্ধতির জন্য +1। যদিও ইতিমধ্যে সরবরাহ করা উত্তরগুলির মতো পরিষ্কার নয়। এমনকি সহজতম প্রস্তাবিত সমাধানও এই উত্তরটির চেয়ে def ONE(): return 1ব্যবহার করা সহজ । ONE()ONE.value
টুলমেকারস্টেভ

7

দুর্ভাগ্যক্রমে পাইথনের এখনও কোনও ধ্রুবক নেই এবং এটি লজ্জাজনক। ইএস 6 ইতিমধ্যে জাভাস্ক্রিপ্টে সমর্থন ধ্রুবক যুক্ত করেছে ( https://developer.mozilla.org/en/docs/Web/JavaScript/References/Statements/const ) যেহেতু এটি কোনও প্রোগ্রামিং ভাষার ক্ষেত্রে খুব দরকারী জিনিস। পাইথন সম্প্রদায়ের অন্যান্য উত্তরে যেমনটি দেওয়া হয়েছে তেমন কনভেনশনটি ব্যবহার করুন - ব্যবহারকারী বড় হাতের অক্ষর হিসাবে পরিবর্তনশীল, তবে এটি কোডটিতে স্বেচ্ছাসেবী ত্রুটিগুলির বিরুদ্ধে সুরক্ষা দেয় না। আপনি যদি চান তবে আপনাকে পরবর্তী হিসাবে একটি একক-ফাইল সমাধান কার্যকর হতে পারে (এটি কীভাবে ব্যবহার করবে ডকাস্ট্রিংগুলি দেখুন)।

ফাইল কনস্ট্যান্টস.পি

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. কাস্টম ধরণের এবং 'ডিক' টাইপটির জন্য সমর্থন করে না

মন্তব্য:

  1. পাইথন 3.4 এবং পাইথন 3.5 দিয়ে পরীক্ষিত (আমি এর জন্য 'টক্স' ব্যবহার করছি)

  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


21
হ্যাঁ, তবে "স্পষ্টভাবে সেট " করার ক্ষমতাটিকে অবরুদ্ধ করাRED = 2 একটি পরিবর্তনশীল নামটিকে "ধ্রুবক" হিসাবে ঘোষণা করতে সক্ষম হওয়ার পুরো সুবিধা (অন্যান্য ভাষায়)!
টুলমেকারস্টেভ

6
আপনি যে ব্লক করে উপকার পাবেন? কনস্টের বিষয়ে সবচেয়ে দরকারী জিনিসটি সাধারণত সংকলক অপটিমাইজেশন যা পাইথনের কোনও জিনিস নয় really ধ্রুব কিছু হতে চান? শুধু এটি পরিবর্তন করবেন না। যদি আপনি অন্য কাউকে এটি পরিবর্তন করার বিষয়ে উদ্বিগ্ন হন তবে আপনি এটিকে কেবল তাদের আওতার বাইরে রেখে দিতে পারেন বা কেবল বুঝতে পারেন যে, কেউ যদি এটি পরিবর্তন করে তবে এটি তাদের সমস্যা এবং তাদের সাথে এটি মোকাবেলা করা দরকার, আপনি নয়।
কেভিন

@ কেভিন: " শ্রেণীর সমস্ত দৃষ্টান্তের জন্য মানটির জন্য একটি একক সঞ্চয়স্থান রাখার সুবিধা " " আপনি কী উপকার পাবেন ... " static? প্রকৃতপক্ষে স্থিতিশীল / শ্রেণীর ভেরিয়েবল ঘোষণা করার সম্ভাবনা না থাকলে।
মিনিট

8
মূল ইস্যুটি হ'ল কেউ কেউ এটিকে এমন একটি মান হিসাবে দেখতে পারে যা সত্যের উত্স, পরিবর্তিত হতে অক্ষম, এবং যাদুর মানগুলি প্রবর্তনের পরিবর্তে তাদের কোড জুড়ে সত্যের উত্স হিসাবে ব্যবহার করতে পারে (যা আমি পাইথনে দেখি) - এবং অন্যরা এটিকে ইচ্ছামত পরিবর্তন করার অনুমতি দেওয়া এমন কিছু হিসাবে দেখতে পাবে। যখন কেউ বিশ্বব্যাপী পরিবর্তনশীল পরিবর্তন করে, এবং এটি কোথায় পরিবর্তন হয়েছে তা আপনি বলতে পারবেন না এবং অ্যাপ্লিকেশন ক্র্যাশ হয়ে গেছে কারণ "লাল" এর পরিবর্তে রেড = "নীল" তখন আপনি একটি সম্পূর্ণ অপ্রয়োজনীয় সমস্যাটি প্রবর্তন করছেন যা ইতিমধ্যে এতটা সহজ সমাধান করা হয়েছে এবং সর্বজনীন বোঝা হয়।
ডাগরুম

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

যদি আমি ফু এর একটি সাবক্লাস তৈরি করি তবে এই শ্রেণিটি তাদের পরিবর্তন করার সম্ভাবনা ছাড়াই ধ্রুবক হিসাবে উত্তরাধিকারী হবে

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

এটি করার কোনও সঠিক উপায় নেই। যেহেতু আমি এটি বুঝতে পেরেছি বেশিরভাগ প্রোগ্রামাররা কেবল শনাক্তকারীকে মূলধন করবে, তাই পিআই = 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"))

দেখে মনে হচ্ছে এটি পিএইচপি-স্টাইলকে ধ্রুব করে তুলবে।

বাস্তবে কারও জন্য মান পরিবর্তন করতে যা লাগে তা হ'ল:

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

আপনি এখানে পাবেন এমন সমস্ত সমাধানগুলির জন্য এটি একই - এমনকি বুদ্ধিমানগুলিও যে একটি শ্রেণি তৈরি করে এবং সেট বৈশিষ্ট্য পদ্ধতিটি পুনরায় সংজ্ঞায়িত করে - তাদের চারপাশে সর্বদা একটি উপায় থাকবে। পাইথন ঠিক তেমনই।

আমার সুপারিশটি হ'ল সমস্ত ঝামেলা এড়ানো এবং কেবল আপনার শনাক্তকারীদের মূলধন করা। এটি সত্যিই সঠিক ধ্রুবক হবে না তবে আবার কিছুই হবে না nothing


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

আপনি স্ট্রিংওয়ার বা ইন্টওয়ার ইত্যাদি ব্যবহার করতে পারেন, আপনার ধ্রুবকটি কনস্ট_ওয়াল

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 , তবে কোনও মন্তব্যে ফিট হয়ে উঠতে এটি খুব বেশি সময় পাচ্ছে, সুতরাং, এটি এখানে যায়))

উপরে উল্লিখিত নেমটুপল পদ্ধতিটি অবশ্যই উদ্ভাবনী। সম্পূর্ণতার জন্য, যদিও, এর অফিসিয়াল ডকুমেন্টেশনের নেমডটপল অংশের শেষে , এটি পড়ে:

নামযুক্ত টিপলস সহ গণিত স্থিরগুলি প্রয়োগ করা যেতে পারে, তবে একটি সাধারণ শ্রেণীর ঘোষণা ব্যবহার করা সহজ এবং আরও দক্ষ:

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

অন্য কথায়, সরকারী ডকুমেন্টেশনের ধরণটি কেবল পঠনযোগ্য আচরণ বাস্তবায়নের পরিবর্তে ব্যবহারিক পদ্ধতি ব্যবহার করতে পছন্দ করে। আমার ধারণা এটি পাইথনের জেনের আরও একটি উদাহরণ হয়ে দাঁড়িয়েছে :

সহজ জটিল চেয়ে ভাল।

ব্যবহারিকতা বিশুদ্ধতা বীট।


2

এখানে এটি ইতিমধ্যে পাওয়া কয়েকটি উত্তরকে উন্নত করার প্রয়াস হিসাবে আমি তৈরি করেছি এমন প্রতিমাগুলির সংগ্রহ is

আমি জানি ধ্রুবক ব্যবহার অজগর নয়, এবং আপনার বাড়িতে এটি করা উচিত নয়!

তবে পাইথন এমন গতিময় ভাষা! এই ফোরামটি দেখায় যে কনস্ট্যান্টগুলির মতো দেখায় এবং বোধ হয় এমন নির্মাণগুলি কীভাবে সম্ভব। ভাষা দ্বারা কী প্রকাশ করা যায় তা অন্বেষণ করার প্রাথমিক উদ্দেশ্য হিসাবে এই উত্তরটি রয়েছে।

দয়া করে আমার সাথে খুব কঠোর হবেন না :-)।

আরও তথ্যের জন্য আমি এই প্রতিমাগুলির সম্পর্কে একটি সহযোগী ব্লগ লিখেছি ।

এই পোস্টে, আমি মানগুলির স্থায়ী রেফারেন্সের জন্য একটি স্থির পরিবর্তনশীলকে কল করব (পরিবর্তনযোগ্য বা অন্যথায়)। তদুপরি, আমি বলি যে কোনও ভেরিয়েবলের হিমায়িত মান থাকে যখন এটি কোনও পরিবর্তনীয় অবজেক্টের উল্লেখ করে যে কোনও ক্লায়েন্ট-কোড তার মান (গুলি) আপডেট করতে পারে না।

ধ্রুবকের একটি স্পেস (স্পেসকনস্ট্যান্টস)

এই প্রবাদটি ধ্রুবক ভেরিয়েবলের (নাম স্পেসকনস্ট্যান্টস) নামের স্থানের মতো দেখতে যা তৈরি করে। এটি অ্যালেক্স মার্টেলির কোড স্নিপেটের একটি পরিবর্তন যা মডিউল অবজেক্টগুলির ব্যবহার এড়াতে পারে। বিশেষ করে, এর পরিমার্জন ব্যবহার কি আমি মধ্যে একটি শ্রেণী কারখানা কল SpaceConstants কাজ, নামক একটি বর্গ 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"

হিমায়িত মানের একটি স্থান (স্পেসফ্রোজেনভ্যালু)

এই পরবর্তী প্রজ্ঞাপনটি স্পেসকনস্ট্যান্টগুলির একটি পরিবর্তন যেখানে রেফারেন্সযুক্ত মিউটটেবল অবজেক্টগুলিকে হিমায়িত করা হয়। এই বাস্তবায়নটি সেট্যাটটর এবং গেটআউটর ফাংশনগুলির মধ্যে আমি ভাগ করে নেওয়া বন্ধ বলে আছি explo পরিবর্তনীয় বস্তুর মান ভেরিয়েবল ক্যাশে দ্বারা অনুলিপি করা হয় এবং রেফারেন্স করা হয় ফাংশন ভাগ করে নেওয়া বন্ধের ভিতরে। আমি রূপান্তরিত অবজেক্টের ক্লোজার সুরক্ষিত অনুলিপিটিকে যা বলে তা এটি গঠন করে

আপনাকে অবশ্যই এই প্রতিমাটি ব্যবহারে সতর্কতা অবলম্বন করতে হবে কারণ গেটআটার গভীর অনুলিপি করে ক্যাশের মান ফিরিয়ে দেয়। এই ক্রিয়াকলাপটি বড় অবজেক্টগুলিতে উল্লেখযোগ্য পারফরম্যান্সের প্রভাব ফেলতে পারে!

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"

একটি ধ্রুবক স্থান (কনস্ট্যান্টস্পেস)

এই আইডিয়ামটি ধ্রুবক ভেরিয়েবল বা কনস্ট্যান্টস্পেসের অপরিবর্তনীয় নেমস্পেস । এটি একটি শ্রেণীর কারখানার সাথে স্ট্যাকওভারফ্লোতে দুর্দান্ত জোন বেটসের জবাবের সংমিশ্রণ ।

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

ধ্রুবকগুলি অপরিবর্তনীয়, তবে ধ্রুবক বাইটায়ারের অ্যাসাইনমেন্ট নিঃশব্দে ব্যর্থ হয়:

>>> 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')

আরও শক্তিশালী, সহজ এবং সম্ভবত আরও বেশি 'পাইথোনিক' পদ্ধতির মধ্যে মেমোরিভিউ অবজেক্টগুলি (<= পাইথন -২. 2. এ বাফার অবজেক্টস) ব্যবহারের সাথে জড়িত।

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)

কনস্টআর আইটেম অ্যাসাইনমেন্টটি হ'ল 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

আমি পাইথন কনস্টের জন্য একটি ইউজ লিবি লিখি : কে কেকনস্ট - পিপিআই সাপোর্ট স্ট্রিং , ইনট, ফ্লোট, ডেটটাইম

কনস্ট ফিল্ড উদাহরণটি তার বেস ধরণের আচরণ রাখবে।

উদাহরণ স্বরূপ:

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 = 'foo'

এবং CONSTANTপরিবর্তিত হবে, তবে CONSTANT[0]এটি স্ক্রিপ্টে প্রথমে ডাকা হবে বলে প্রথমে একটি টাইপরর ছুঁড়ে ফেলা হবে ।

যদিও ... আমি মনে করি আপনি যদি এটির কোনও মুহূর্তে পরিবর্তন করেন

CONSTANT = [1,2,3]

এখন আপনি আর টাইপ-এয়ারার পাবেন না। Hmmmm ....

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.