পাইথনে স্ট্যাটিক ক্লাস ভেরিয়েবলগুলি কি সম্ভব?


উত্তর:


1898

পরিবর্তনগুলি শ্রেণীর সংজ্ঞার ভিতরে ঘোষণা করা হয় তবে কোনও পদ্ধতির অভ্যন্তরে নয় শ্রেণি বা স্ট্যাটিক ভেরিয়েবলগুলি:

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

@ মিলারদেব যেমন উল্লেখ করেছেন, এটি একটি শ্রেণি-স্তরের iভেরিয়েবল তৈরি করে , তবে এটি কোনও উদাহরণ-স্তরের iভেরিয়েবলের থেকে পৃথক, তাই আপনি থাকতে পারেন

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

এটি সি ++ এবং জাভা থেকে পৃথক, তবে সি # থেকে এতটা আলাদা নয়, যেখানে কোনও ঘটনার রেফারেন্স ব্যবহার করে কোনও স্থির সদস্য অ্যাক্সেস করতে পারে না।

ক্লাস এবং শ্রেণীর বিষয়গুলির বিষয়ে পাইথন টিউটোরিয়ালটি কী বলে তা দেখুন ।

@ স্টিভ জনসন ইতিমধ্যে স্ট্যাটিক পদ্ধতি সম্পর্কে উত্তর দিয়েছেন , পাইথন লাইব্রেরি রেফারেন্সে "বিল্ট-ইন ফাংশন" এর অধীনেও নথিভুক্ত ।

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

@ বিডি ক্ল্যাসমেডোস্টকে স্ট্যাটিকমেডোস্টের ওপরে সুপারিশ করেন, কারণ পদ্ধতিটি প্রথম শ্রেণীর ধরণের হিসাবে প্রথম যুক্তি হিসাবে গ্রহণ করে তবে স্ট্যাটিকমেডোথের চেয়ে এই পদ্ধতির সুবিধা সম্পর্কে আমি এখনও কিছুটা অস্পষ্ট uzz যদি আপনিও হন তবে সম্ভবত এটি কোনও বিষয় নয়।


11
আমি শুধু পাইথন শিখছি, কিন্তু সুবিধার @classmethodউপর @staticmethodআমি যতদূর জানি যে আপনি সবসময়, বর্গ পদ্ধতির উপর প্রার্থনা ছিল নাম পেতে এমনকি যদি এটি একটি উপশ্রেণী হয়। একটি স্থিতিশীল পদ্ধতিতে এই তথ্যের অভাব হয়, সুতরাং এটি একটি ওভাররাইড পদ্ধতিতে কল করতে পারে না, উদাহরণস্বরূপ।
Seb

49
@ জ্যালিসিনে ধ্রুবকগুলির জন্য অজগর উপায়টি ধ্রুবকদের জন্য কোনও শ্রেণি বৃদ্ধি করা নয়। কিছু const.pyসহ কিছু রাখুন PI = 3.14এবং আপনি এটিকে সর্বত্র আমদানি করতে পারেন। from const import PI
গিজমো

29
এই উত্তরটি স্থির পরিবর্তনশীল ইস্যুকে বিভ্রান্ত করার সম্ভাবনা রয়েছে to দিয়ে শুরু করতে, i = 3হয় না একটি স্ট্যাটিক পরিবর্তনশীল, এটা একটা বর্গ অ্যাট্রিবিউট, এবং যেহেতু এটি একটি দৃষ্টান্ত-স্তরের বৈশিষ্ট্য থেকে স্বতন্ত্র iএটি নেই না অন্যান্য ভাষায় একটি স্ট্যাটিক পরিবর্তনশীল মত আচরণ। দেখুন millerdev এর উত্তর , Yann এর উত্তর , এবং আমার উত্তর নিচে।
রিক

2
সুতরাং আমি i(ক্ল্যাটিক ভেরিয়েবল) কেবলমাত্র একটি অনুলিপি স্মৃতিতে থাকবে যদি আমি এই শ্রেণীর শত শত উদাহরণ তৈরি করি?
sdream

2
ড্যানিয়েল যিনি @ ডাবস্লো মন্তব্যে উল্লেখ করেছেন যে কারও আগ্রহী তাদের পক্ষে, এটি মিলারদেব ( ওয়েবব্যাক মেশিন )
আরে

616

@ ব্লেয়ার কনরাড বলেছেন স্ট্যাটিক ভেরিয়েবলগুলি শ্রেণীর সংজ্ঞার অভ্যন্তরে ঘোষণা করা হয়েছে তবে কোনও পদ্ধতির অভ্যন্তরে শ্রেণি বা "স্থিতিশীল" ভেরিয়েবলগুলি নেই:

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

এখানে কয়েকটি গোছা আছে। উপরের উদাহরণ থেকে বহন করা:

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

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

লক্ষ্য করুন t.iযে বৈশিষ্ট্যটি iসরাসরি চালু করা হলে কীভাবে উদাহরণ চলকটি "স্থিতিশীল" শ্রেণীর ভেরিয়েবলের সাথে সিঙ্কের বাইরে চলে যায় t। এর কারণটি iনামপথের মধ্যে পুনরায় আবদ্ধ ছিল tযা Testনামস্থান থেকে পৃথক । আপনি যদি কোনও "স্ট্যাটিক" ভেরিয়েবলের মান পরিবর্তন করতে চান তবে আপনাকে অবশ্যই এটির সুযোগ (বা অবজেক্ট) এর মধ্যে পরিবর্তন করতে হবে যেখানে এটি মূলত সংজ্ঞায়িত হয়েছিল। আমি উদ্ধৃতিগুলিতে "স্ট্যাটিক" রেখেছি কারণ সি ++ এবং জাভা যে অর্থে পাইথনের স্থিতিশীল ভেরিয়েবল নেই।

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

@ স্টিভ জনসন স্ট্যাটিক পদ্ধতি সম্পর্কেও উত্তর দিয়েছেন, পাইথন লাইব্রেরি রেফারেন্সে "বিল্ট-ইন ফাংশন" এর অধীনেও নথিভুক্ত করা হয়েছে।

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

@ বিয়েড ক্লাসমেডথেরও উল্লেখ করেছেন, যা স্ট্যাটিকমেডথের অনুরূপ। শ্রেণিবদ্ধের প্রথম যুক্তি হ'ল শ্রেণি বস্তু। উদাহরণ:

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

উপরের উদাহরণের চিত্রের উপস্থাপনা


3
আমি আপনাকে উদাহরণটি সামান্য প্রসারিত করার পরামর্শ দিচ্ছি: যদি, Test.i = 6 সেট করার পরে আপনি একটি নতুন অবজেক্ট ইনস্ট্যান্ট করেন (যেমন, u = পরীক্ষা ()), নতুন অবজেক্টটি নতুন শ্রেণীর মানকে "উত্তরাধিকারী" করবে (যেমন, UI == 6)
মার্ক

2
সুসংগত স্ট্যাটিক ভেরিয়েবল রাখার একটি উপায় তাদের বৈশিষ্ট্য করা: class Test(object):, _i = 3, @property, def i(self), return type(self)._i, @i.setter, def i(self,val):, type(self)._i = val। এখন আপনি কি করতে পারেন x = Test(), x.i = 12, assert x.i == Test.i
রিক 15

1
সুতরাং আমি বলতে পারি যে সমস্ত ভেরিয়েবল শুরুতে স্থির এবং তারপরে অ্যাক্সেসগুলি অ্যাক্সেস করা রানটাইমের ক্ষেত্রে উদাহরণ পরিবর্তনশীল করে তোলে?
আলী

সম্ভবত এটি আকর্ষণীয়: আপনি যদি টেস্টে এমন কোনও পদ্ধতি নির্ধারণ করেন যা টেস্ট.আই পরিবর্তন করে, যা উভয় টেস্ট.আই এবং টিআই মানগুলিকে প্রভাবিত করবে।
পাবলো

@ মিলারদেব, যেমন আপনি উল্লিখিত পাইথনের সি ++ বা জাভা হিসাবে স্ট্যাটিক ভেরিয়েবল নেই..তাই কি বলা ঠিক হবে, টেস্ট.আই একটি স্ট্যাটিক ভেরিয়েবলের চেয়ে ক্লাস ভেরিয়েবলের বেশি?
টাইটো

197

স্ট্যাটিক এবং ক্লাস পদ্ধতি

অন্যান্য উত্তরগুলি যেমন উল্লেখ করেছে, স্থিতিশীল এবং শ্রেণিবদ্ধ পদ্ধতিগুলি বিল্ট-ইন সজ্জা ব্যবহার করে সহজেই সম্পন্ন হয়:

class Test(object):

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

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

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

যথারীতি, প্রথম আর্গুমেন্টটি MyMethod()ক্লাস ইনস্ট্যান্স অবজেক্টের সাথে আবদ্ধ। এর বিপরীতে, প্রথম যুক্তি MyClassMethod()হয় বর্গ বস্তুর নিজেই আবদ্ধ (যেমন, এই ক্ষেত্রে, Test)। কারণ MyStaticMethod(), কোনও যুক্তিই আবদ্ধ নয় এবং যুক্তি থাকা মোটেই allচ্ছিক নয়।

"স্ট্যাটিক ভেরিয়েবলস"

তবে, "স্ট্যাটিক ভেরিয়েবল" প্রয়োগ করা (ভাল, মিউটেবল স্ট্যাটিক ভেরিয়েবলগুলি, যাইহোক, যদি এটি শর্তগুলির মধ্যে বৈপরীত্য না হয় ...) তত সোজা সামনের দিকে নয়। মিলারদেব তার উত্তরে যেমন উল্লেখ করেছেন , সমস্যাটি হচ্ছে পাইথনের শ্রেণিবদ্ধ বৈশিষ্ট্যগুলি সত্যই "স্ট্যাটিক ভেরিয়েবল" নয়। বিবেচনা:

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

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

কারণ লাইন এই x.i = 12নতুন ইনস্ট্যান্স অ্যাট্রিবিউট যোগ করেনি iথেকে xপরিবর্তে মান পরিবর্তন Testবর্গ iঅ্যাট্রিবিউট।

আংশিক প্রত্যাশিত স্ট্যাটিক পরিবর্তনশীল আচরণ, অর্থাত, একাধিক দৃষ্টান্ত মধ্যে গুণাবলীর সিঙ্ক (কিন্তু না বর্গ নিজেই সঙ্গে; নিচে দেখুন "gotcha হয়"), একটি সম্পত্তি ক্লাসটি চালু করার মাধ্যমে অর্জন করা যেতে পারে:

class Test(object):

    _i = 3

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

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

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

class Test(object):

    _i = 3

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

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

    i = property(get_i, set_i)

এখন আপনি এটি করতে পারেন:

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

স্ট্যাটিক ভেরিয়েবল এখন সমস্ত শ্রেণীর উদাহরণগুলির মধ্যে সিঙ্কে থাকবে ।

(দ্রষ্টব্য: এটি, যদি না কোনও শ্রেণীর উদাহরণ তার নিজস্ব সংস্করণটি সংজ্ঞায়িত করার সিদ্ধান্ত না নেয় _i! তবে কেউ যদি এটি করার সিদ্ধান্ত নেয় তবে তারা যা পাবে তার প্রাপ্য, তাই না ???)

নোট করুন যে প্রযুক্তিগতভাবে বলতে গেলে iএখনও 'স্ট্যাটিক ভেরিয়েবল' নয়; এটি একটি property, যা একটি বিশেষ ধরণের বর্ণনাকারী। যাইহোক, propertyআচরণটি এখন সমস্ত শ্রেণীর দৃষ্টান্তে সিঙ্ক করা একটি (পরিবর্তনযোগ্য) স্ট্যাটিক ভেরিয়েবলের সমান।

অপরিবর্তনীয় "স্ট্যাটিক ভেরিয়েবলস"

অপরিবর্তনীয় স্থির পরিবর্তনশীল আচরণের জন্য, কেবলমাত্র সেটটার বাদ দিন property:

class Test(object):

    _i = 3

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

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

class Test(object):

    _i = 3

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

    i = property(get_i)

উদাহরণস্বরূপ iবৈশিষ্ট্যটি সেট করার চেষ্টা করার পরে একটি ফেরত আসবে AttributeError:

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

একজন সচেতন হতে হবে

লক্ষ্য করুন যে উপরের পদ্ধতিগুলি কেবল আপনার শ্রেণীর উদাহরণগুলির সাথে কাজ করে - ক্লাসটি নিজেই ব্যবহার করার সময় সেগুলি কাজ করবে না । উদাহরণস্বরূপ:

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

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

লাইনটি assert Test.i == x.iএকটি ত্রুটি তৈরি করে, কারণ এর iবৈশিষ্ট্য Testএবং xদুটি পৃথক বস্তু।

অনেকেই অবাক করে দেবেন। তবে এটি হওয়া উচিত নয়। যদি আমরা ফিরে যাই এবং আমাদের Testশ্রেণীর সংজ্ঞা (দ্বিতীয় সংস্করণ) পরীক্ষা করি তবে আমরা এই রেখার নোটটি নিই:

    i = property(get_i) 

স্পষ্টত, সদস্য iএর Testআবশ্যক হতে propertyবস্তু, যার বস্তুর ধরণ থেকে ফিরে আসেন propertyফাংশন।

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

আমি নীচে উপরের 'গোটচা' এর একটি সমাধান উপস্থাপন করছি; তবে আমি পরামর্শ দিচ্ছি - দৃren়তার সাথে - যে আপনি নীচের মতো কিছু করার চেষ্টা করবেন না - সর্বনিম্ন - আপনি কেন পুরোপুরি assert Test.i = x.iত্রুটি ঘটায় তা পুরোপুরি বুঝতে পারবেন ।

বাস্তব, বাস্তব স্ট্যাটিক চলক -Test.i == x.i

আমি নীচে (পাইথন 3) সমাধানটি কেবল তথ্যের জন্য উপস্থাপন করছি। আমি এটি একটি "ভাল সমাধান" হিসাবে সমর্থন করি না। পাইথনের অন্যান্য ভাষার স্থির পরিবর্তনশীল আচরণ অনুকরণ করা আসলেই প্রয়োজনীয় কিনা তা নিয়ে আমার সন্দেহ রয়েছে। তবে এটি আসলে কার্যকর কিনা তা নির্বিশেষে নীচে পাইথন কীভাবে কাজ করে তা আরও বুঝতে সহায়তা করা উচিত।

আপডেট: এই প্রচেষ্টা সত্যই ভয়ঙ্কর ; যদি আপনি এই জাতীয় কিছু করার জন্য জেদ করেন (ইঙ্গিত: দয়া করে করবেন না; পাইথন একটি খুব মার্জিত ভাষা এবং এটি অন্য ভাষার মতো আচরণ করার জন্য জুতো-হর্নিং করা কেবল প্রয়োজনীয় নয়), পরিবর্তে ইথান ফুরম্যানের উত্তরে কোডটি ব্যবহার করুন ।

একটি মেটাক্লাস ব্যবহার করে অন্যান্য ভাষার স্থির পরিবর্তনশীল আচরণ অনুকরণ করা

একটি মেটাক্লাস একটি শ্রেণীর শ্রেণি। পাইথনের সমস্ত শ্রেণীর জন্য ডিফল্ট মেটাক্লাস (অর্থাত, "নতুন স্টাইল" ক্লাস পোস্ট পাইথন ২.৩-এর আমি বিশ্বাস করি) type। উদাহরণ স্বরূপ:

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

তবে আপনি নিজের মেটাগ্লাস এর মতো সংজ্ঞা দিতে পারেন:

class MyMeta(type): pass

এবং এটি আপনার নিজের ক্লাসে এটি প্রয়োগ করুন (কেবল পাইথন 3):

class MyClass(metaclass = MyMeta):
    pass

type(MyClass)  # class MyMeta

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

"স্ট্যাটিক ভেরিয়েবল" এর একটি ক্যাটালগ বৈশিষ্ট্যে সংরক্ষণ করা হয় StaticVarMeta.statics। সমস্ত অ্যাট্রিবিউট অনুরোধগুলি প্রথমে বিকল্প রেজোলিউশন অর্ডার ব্যবহার করে সমাধান করার চেষ্টা করা হয়। আমি এটিকে "স্ট্যাটিক রেজোলিউশন অর্ডার", বা "এসআরও" ডাব করেছি। প্রদত্ত শ্রেণীর (বা এর প্যারেন্ট ক্লাস) জন্য "স্ট্যাটিক ভেরিয়েবল" এর সেটটিতে অনুরোধকৃত বৈশিষ্ট্যটি অনুসন্ধান করে এটি করা হয়। বৈশিষ্ট্যটি যদি "এসআরও" তে উপস্থিত না হয়, ক্লাসটি ডিফল্ট অ্যাট্রিবিউট গেট / সেট / ডিলিট আচরণ (যেমন, "এমআরও") এ ফিরে আসবে।

from functools import wraps

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

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

    Example usage: 

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

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

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

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

আমি আপনার উপায়টি ব্যবহার করার চেষ্টা করেছি তবে আমি একটি সমস্যার মুখোমুখি হয়েছি, দয়া করে এখানে আমার প্রশ্নটি দেখুন দয়া করে stackoverflow.com/questions/29329850/get-static-variable-value
মুহাম্মাদ রেফায়াত

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

1
@ রিকটিচি ধন্যবাদ :-) শেষে আপনার মেটাক্লাসটি আকর্ষণীয় তবে আমার পছন্দ হিসাবে এটি কিছুটা জটিল complex এটি কোনও বৃহত কাঠামো / প্রয়োগে কার্যকর হতে পারে যেখানে এই প্রক্রিয়াটি একেবারে প্রয়োজনীয়। যাইহোক, এটি উদাহরণস্বরূপ যে নতুন (জটিল) অ-ডিফল্ট মেটা-আচরণটি সত্যই প্রয়োজন হলে পাইথন এটি সম্ভব করে তোলে :)
ওলে থমসন বুস

1
@ ওলি থমসনবুউস: কাজটি করে এমন একটি সহজ মেটাক্লাসের জন্য আমার উত্তরটি পরীক্ষা করুন ।
ইথান ফুরম্যান

1
@ টেপার আপনি সঠিক; সমস্যার সমাধানের জন্য আমি উত্তরটি সম্পাদনা করেছি (বিশ্বাস করতে পারছি না যে এটি এত দিন ধরে ভুল করে বসেছিল!)। বিভ্রান্তির জন্য দুঃখিত.
রিক

33

আপনি ফ্লাইয়ের ক্লাসে ক্লাস ভেরিয়েবলগুলিও যুক্ত করতে পারেন

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

এবং শ্রেণীর উদাহরণ ক্লাস ভেরিয়েবল পরিবর্তন করতে পারে

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

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

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

3
ক্লাসটি অন্য মডিউলে আমদানি করা হলেও নতুন ক্লাসের ভেরিয়েবলগুলি কি আটকে থাকবে?
জাকদানিস

হ্যাঁ. ক্লাসগুলি আপনি যে নাম ঠিকানাটি থেকে কল করেছেন তা নির্বিশেষে কার্যকরভাবে সিঙ্গেলন।
পেড্রো

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

19

আমি যখনই স্থির পদ্ধতির প্রয়োজন তখন ব্যক্তিগতভাবে আমি একটি শ্রেণিবদ্ধ ব্যবহার করতাম। মূলত কারণ আমি একটি যুক্তি হিসাবে ক্লাস পেতে।

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

বা একটি সজ্জা ব্যবহারকারীর

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

স্থির বৈশিষ্ট্যের জন্য .. এটি সময় আপনি কিছু অজগর সংজ্ঞা সন্ধান করেন .. পরিবর্তনশীল সর্বদা পরিবর্তন হতে পারে। এগুলির দুটি ধরণের পরিবর্তনীয় এবং অপরিবর্তনীয় .. এছাড়াও, শ্রেণি বৈশিষ্ট্য এবং উদাহরণ বৈশিষ্ট্য রয়েছে .. জাভা এবং সি ++ অর্থে স্থির গুণাবলীর মতো আসলে কিছুই নেই

অজগর দিক থেকে স্থির পদ্ধতিটি কেন ব্যবহার করুন, যদি শ্রেণীর সাথে তার কোনও সম্পর্ক না থাকে! আমি যদি আপনি থাকতাম তবে আমি হয় শ্রেণিবদ্ধ ব্যবহার করতাম বা ক্লাস থেকে আলাদা পদ্ধতিটি সংজ্ঞায়িত করতাম।


1
চলকগুলি পরিবর্তনীয় বা পরিবর্তনযোগ্য নয়; বস্তু হয়। (তবে, কোনও অবজেক্ট, সাফল্যের বিভিন্ন ডিগ্রি সহ, এর কয়েকটি বৈশিষ্ট্যকে অ্যাসাইনমেন্ট আটকাতে চেষ্টা করতে পারে))
ডেভিস হেরিং

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

16

স্থিতিশীল বৈশিষ্ট্য এবং উদাহরণের বৈশিষ্ট্যগুলি সম্পর্কে নীচের উদাহরণে দেখানো একটি বিশেষ বিষয়:

class my_cls:
  my_prop = 0

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

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

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

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

উদাহরণস্বরূপ সম্পত্তিটিকে মান নির্ধারণের আগে এর অর্থ, যদি আমরা 'উদাহরণস্বরূপ সম্পত্তিটি অ্যাক্সেস করার চেষ্টা করি তবে স্ট্যাটিক মানটি ব্যবহৃত হয়। প্রতিটি সম্পত্তি পাইথন ক্লাসে ঘোষণা সবসময় স্মরণে একটি স্ট্যাটিক স্লট আছে


16

পাইথনে স্ট্যাটিক পদ্ধতিগুলিকে ক্লাসমেড এস বলা হয় । নীচের কোডটি একবার দেখুন

class MyClass:

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

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

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

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

লক্ষ্য করুন যে যখন আমরা পদ্ধতিটি আমার ইনস্ট্যান্সমেথোদ বলি তখন আমরা একটি ত্রুটি পাই। এটি কারণ এই শ্রেণীর উদাহরণ হিসাবে প্রয়োজন যে পদ্ধতি প্রয়োজন। পদ্ধতি myStaticMethod একটি classmethod ব্যবহার সেট করা হয় প্রসাধক @classmethod

কেবল লাথি এবং গিগলসের জন্য, ক্লাসের কোনও উদাহরণ দিয়ে পাস করে আমরা ক্লাসে আমারআইন্সটেন্স মেথডকে কল করতে পারি :

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

2
উম্ম ... স্ট্যাটিক পদ্ধতিগুলি দিয়ে তৈরি করা হয় @staticmethod; @classmethodশ্রেণি পদ্ধতিগুলির জন্য (স্পষ্টতই) হ'ল (যা প্রাথমিকভাবে বিকল্প নির্মাতা হিসাবে ব্যবহারের উদ্দেশ্যে তৈরি করা হয়, তবে স্থির পদ্ধতি হিসাবে একটি চিমটিতে পরিবেশন করতে পারে যা তাদের মাধ্যমে ডাকা হত এমন শ্রেণীর একটি রেফারেন্স গ্রহণ করে)।
শ্যাডোর্যাঞ্জার

11

কোনও সদস্য পদ্ধতির বাইরে কিছু সদস্য ভেরিয়েবল সংজ্ঞায়িত করার সময়, চলকটি কীভাবে প্রকাশিত হয় তার উপর নির্ভর করে স্থির বা স্থিতিশীল হতে পারে।

  • CLASSNAME.var স্থির পরিবর্তনশীল
  • INSTANCENAME.var স্থির পরিবর্তনশীল নয়।
  • self.var বর্গের ভিতরে স্থির পরিবর্তনশীল নয়।
  • শ্রেণীর সদস্য ফাংশনের ভিতরে var সংজ্ঞায়িত হয় না।

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

#!/usr/bin/python

class A:
    var=1

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


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

    A.var = 3
    a.printvar()

ফলাফল হয়

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

ইন্ডেন্টেশনটি নষ্ট হয়ে গেছে। এটি কার্যকর করা হবে না
টমাস ওয়েলার

9

staticক্লাস ভেরিয়েবল থাকা সম্ভব , তবে সম্ভবত চেষ্টাটির পক্ষে মূল্য নেই।

পাইথন 3-তে একটি প্রুফ-অফ কনসেপ্ট লিখিত আছে - সঠিক বিবরণগুলির কোনওটি ভুল হলে কোডটি টুইঙ্ক করা যেতে পারে যার অর্থ আপনি যা বলছেন তা static variable:


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

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

এবং ব্যবহারে:

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

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

এবং কিছু পরীক্ষা:

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

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

8

আপনি মেটাক্লাস ব্যবহার করে অবিচলিত হতে কোনও শ্রেণি প্রয়োগ করতে পারেন।

class StaticClassError(Exception):
    pass


class StaticClass:
    __metaclass__ = abc.ABCMeta

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

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

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

তারপরে যখনই দুর্ঘটনাক্রমে আপনি মাইক্লাসকে আরম্ভ করার চেষ্টা করবেন আপনি একটি স্ট্যাটিকক্লাসেরর পাবেন।


4
আপনি এটি ইনস্ট্যান্ট করতে যাচ্ছেন না কেন এটি এমনকি একটি শ্রেণি কেন? এটিকে জাভাতে পরিণত করার জন্য পাইথনকে বাঁকানোর মতো মনে হচ্ছে ....
নেড ব্যাচেল্ডার

1
Borg বাগ্ধারা এই হ্যান্ডেল করার জন্য একটি ভাল উপায় নেই।
মনিকাকে

@ নেড ব্যাচেল্ডার এটি একটি বিমূর্ত শ্রেণি, কেবলমাত্র সাবক্লাসিংয়ের জন্য (এবং
উপক্লাসগুলি

1
আমি আশা করি সাবক্লাসগুলি __new__তার পিতামাতার আহ্বান জানাতে সুপার () ব্যবহার করবে না ...
নেড ব্যাচেল্ডার

7

পাইথনের বৈশিষ্ট্য অনুসন্ধান সম্পর্কে একটি আকর্ষণীয় বিষয় হ'ল এটি " ভার্চুয়াল ভেরিয়েবল" তৈরি করতে ব্যবহার করা যেতে পারে :

class A(object):

  label="Amazing"

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

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

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

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

এগুলি তৈরি করার পরে সাধারণত এগুলিতে কোনও অ্যাসাইনমেন্ট নেই। লক্ষ্য করুন যে অনুসন্ধানটি ব্যবহার করেছে selfকারণ, যদিও labelকোনও নির্দিষ্ট উদাহরণের সাথে সম্পর্কিত না হওয়ার দিক থেকে এটি স্থিতিশীল , তবুও মানটি (উদাহরণের শ্রেণীর) উপর নির্ভর করে।


6

এই উত্তরের প্রসঙ্গে , একটি ধ্রুবক স্ট্যাটিক ভেরিয়েবলের জন্য, আপনি একটি বর্ণনাকারী ব্যবহার করতে পারেন। এখানে একটি উদাহরণ:

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

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

    def __set__(self, obj, val):
        pass


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


class SubDemo(Demo):
    x = 10


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

ফলে ...

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

যদি আপনি চুপচাপ সেটিং মান ( passউপরে) উপেক্ষা না করেন তবে আপনি সর্বদা একটি ব্যতিক্রম বাড়াতে পারেন । আপনি যদি কোনও সি ++ খুঁজছেন, জাভা স্টাইলের স্ট্যাটিক ক্লাস ভেরিয়েবল:

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

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

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

কটাক্ষপাত আছে এই উত্তর এবং সরকারী দস্তাবেজ হাওটুর বর্ণনাকারী সম্পর্কে আরও তথ্যের জন্য।


2
আপনি কেবল ব্যবহার করতে পারেন @property, যা ডেস্ক্রিপ্টর ব্যবহার করার মতো, তবে এটি অনেক কম কোড।
রিক

6

একেবারে হ্যাঁ, পাইথনের নিজেই কোনও স্ট্যাটিক ডেটা সদস্য স্পষ্টভাবে নেই, তবে আমরা এটি করে থাকতে পারি

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

আউটপুট

0
0
1
1

ব্যাখ্যা

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

6

হ্যাঁ, অজগরটিতে স্থির পরিবর্তনশীল এবং পদ্ধতিগুলি অবশ্যই লেখা সম্ভব।

স্ট্যাটিক ভেরিয়েবলস: ক্লাস স্তরে ঘোষিত চলককে স্ট্যাটিক ভেরিয়েবল বলা হয় যা শ্রেণীর নাম ব্যবহার করে সরাসরি অ্যাক্সেস করা যায়।

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

    >>> print(A.my_var)
        shagun

ইনস্ট্যান্স ভেরিয়েবল: কোনও শ্রেণীর উদাহরণ অনুসারে সম্পর্কিত এবং অ্যাক্সেস হওয়া ভেরিয়েবলগুলি হ'ল উদাহরণ ভেরিয়েবল।

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

স্থির পদ্ধতি: অনুরূপ, স্থির পদ্ধতিগুলি শ্রেণীর নাম ব্যবহার করে সরাসরি অ্যাক্সেস করা যায়। উদাহরণ তৈরি করার দরকার নেই।

তবে মনে রাখবেন, একটি স্ট্যাটিক পদ্ধতি পাইথনটিতে একটি অ-স্থিতির পদ্ধতিতে কল করতে পারে না।

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

4

কোনও সম্ভাব্য বিভ্রান্তি এড়াতে, আমি স্থিতিশীল ভেরিয়েবল এবং অপরিবর্তনীয় বস্তুর বিপরীতে চাই।

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

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


4

আমি খুঁজে পেয়েছি সবচেয়ে ভাল উপায় হ'ল অন্য ক্লাস ব্যবহার করা। আপনি একটি বস্তু তৈরি করতে পারেন এবং তারপরে এটি অন্য বস্তুগুলিতে ব্যবহার করতে পারেন।

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

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

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

উপরের উদাহরণ দিয়ে আমি একটি ক্লাস তৈরি করেছি staticFlag

এই শ্রেণীর স্ট্যাটিক ভার __success(প্রাইভেট স্ট্যাটিক ভার) উপস্থাপন করা উচিত ।

tryIt ক্লাসটি আমাদের নিয়মিত ক্লাসের প্রতিনিধিত্ব করে।

এখন আমি একটি পতাকার জন্য একটি বস্তু তৈরি করেছি (staticFlag ) এর । নিয়মিত সমস্ত বস্তুর রেফারেন্স হিসাবে এই পতাকাটি প্রেরণ করা হবে।

এই সমস্ত বস্তু তালিকায় যুক্ত করা হচ্ছে tryArr


এই স্ক্রিপ্ট ফলাফল:

False
False
False
False
False
True
True
True
True
True

2

ক্লাস কারখানায় স্ট্যাটিক ভেরিয়েবলগুলি 3

পাইথন ৩..6 এর সাথে ক্লাস ফ্যাক্টরি ব্যবহার করে এমন কেউ এবং nonlocalতার জন্য তৈরি করা ক্লাসের সুযোগ / প্রসঙ্গে যুক্ত করতে কীওয়ার্ডটি ব্যবহার করুন :

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

হ্যাঁ, তবে এই ক্ষেত্রে hasattr(SomeClass, 'x')হয় False। আমি সন্দেহ করি এটাই যে কেউ স্ট্যাটিক ভেরিয়েবল বলতে চাইছেন।
রিক

@RickTeachey তোমার, আপনার স্ট্যাটিক পরিবর্তনশীল কোড, দেখেছি stackoverflow.com/a/27568860/2026508 +1 টি ইন্টারনেট স্যার, এবং আমি hasattr যে ভালো কাজ করে নি ভেবেছি? সুতরাং পরিবর্তনযোগ্য some_var, এবং স্থিতিশীলভাবে সংজ্ঞায়িত করা হয়, বা এটি না? বহিরাগত গেটর অ্যাক্সেসের সাথে একটি পরিবর্তনশীল স্থির বা না থাকার সাথে কী করতে পারে? আমার এখন অনেক প্রশ্ন আছে। আপনি সময় পেলে কিছু উত্তর শুনতে পছন্দ করবেন।
জমুনসচ

হ্যাঁ মেটাক্লাসটি বেশ হাস্যকর। আমি নিশ্চিত না যে আমি প্রশ্নগুলি বুঝতে পেরেছি তবে আমার মনে, some_varউপরেরটি কোনও শ্রেণির সদস্য নয়। পাইথনে সমস্ত শ্রেণীর সদস্যদের ক্লাসের বাইরে থেকে প্রবেশ করা যায়।
রিক

nonlocalKeywoard পরিবর্তনশীল এর সুযোগ "বাধা বিপত্তি"। শ্রেণীর বডি সংজ্ঞার ক্ষেত্রটি নিজের মধ্যে যে সুযোগটি খুঁজে পায় তার থেকে পৃথক- যখন আপনি বলবেন nonlocal some_var, এটি কেবলমাত্র একটি অ-স্থানীয় তৈরি করছে (পড়ুন: শ্রেণির সংজ্ঞা স্কোপে নেই) অন্য নামকৃত অবজেক্টের নামের রেফারেন্স। সুতরাং এটি শ্রেণীর সংজ্ঞার সাথে সংযুক্ত হয় না কারণ এটি শ্রেণীর দেহের স্কোপে নেই।
রিক

1

সুতরাং এটি সম্ভবত একটি হ্যাক, তবে আমি eval(str)অজগর 3 এ স্ট্যাটিক অবজেক্ট, একধরণের বৈপরীত্য পাওয়ার জন্য ব্যবহার করছি ।

একটি রেকর্ডস.পি ফাইল রয়েছে যা classস্থির পদ্ধতি এবং নির্মাতাদের সাথে সংজ্ঞায়িত অবজেক্টগুলি ব্যতীত আর কিছু নেই যা কিছু যুক্তি সংরক্ষণ করে। তারপরে অন্য .py ফাইল থেকে আমি import Recordsকিন্তু আমার প্রতিটি বস্তুটি গতিশীলভাবে নির্বাচন করতে হবে এবং তারপরে যে পরিমাণ ডেটা পড়া হচ্ছে সে অনুযায়ী চাহিদা অনুসারে তা ইনস্ট্যান্ট করা দরকার।

সুতরাং যেখানে object_name = 'RecordOne'বা শ্রেণীর নাম, আমি কল করি cur_type = eval(object_name)এবং তারপরে এটি ইনস্ট্যান্ট করার জন্য cur_inst = cur_type(args) যাইহোক আপনি ইনস্ট্যান্ট করার আগে cur_type.getName()যেমন স্থির পদ্ধতিগুলি কল করতে পারেন উদাহরণস্বরূপ, বিমূর্ত বেস শ্রেণীর প্রয়োগের মতো বা লক্ষ্য যাই হোক না কেন। তবে ব্যাকএন্ডে সম্ভবত এটি অজগরটিতে তাত্ক্ষণিকভাবে ইনস্ট্যান্টেশনযুক্ত এবং সত্যই স্থির নয়, কারণ ইভাল কোনও বস্তু ফিরিয়ে দিচ্ছে .... যা অবশ্যই তাত্ক্ষণিকভাবে করা উচিত .... যা আচরণের মতো স্থির করে দেয়।


0

উদাহরণগুলির মধ্যে "স্থির আচরণ" পেতে আপনি একটি তালিকা বা অভিধান ব্যবহার করতে পারেন।

class Fud:

     class_vars = {'origin_open':False}

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


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

         return Fud(False)


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


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

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

fud1.close()

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

0

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

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

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

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


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

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


if __name__ == "__main__":
    workers = Workers()
    for item in (('Fiona', '0009898'), ('Maria', '66328191'), ("Sandra", '2342184'), ('Elvira', '425872')):
        workers.add(item[0], item[1])
    for worker in workers.list:
        print(worker)
    print("next id: %i" % Worker.id)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.