第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

靜態(tài)類變量是否可能?

靜態(tài)類變量是否可能?

慕斯王 2019-05-27 10:07:07
靜態(tài)類變量是否可能?是否有可能在python中有靜態(tài)類變量或方法?這樣做需要什么語(yǔ)法?
查看完整描述

4 回答

?
揚(yáng)帆大魚

TA貢獻(xiàn)1799條經(jīng)驗(yàn) 獲得超9個(gè)贊

在類定義中聲明但在方法內(nèi)部未聲明的變量是類或靜態(tài)變量:

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

正如@millerdev所指出的,這會(huì)創(chuàng)建一個(gè)類級(jí)i變量,但這與任何實(shí)例級(jí)i變量都不同,所以你可以擁有

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

這與C ++和Java不同,但與C#沒有什么不同,在C#中,使用對(duì)實(shí)例的引用無(wú)法訪問(wèn)靜態(tài)成員。

了解Python教程對(duì)類和類對(duì)象主題的看法

@Steve Johnson已經(jīng)回答了有關(guān)靜態(tài)方法的問(wèn)題,也在Python Library Reference的“內(nèi)置函數(shù)”中進(jìn)行了介紹。

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

@beidy建議使用方法而不是static 方法,因?yàn)樵摲椒ń邮疹愵愋妥鳛榈谝粋€(gè)參數(shù),但我對(duì)這種方法相對(duì)于靜態(tài)方法的優(yōu)勢(shì)仍然有點(diǎn)模糊。如果你也是,那么它可能并不重要。


查看完整回答
反對(duì) 回復(fù) 2019-05-27
?
蠱毒傳說(shuō)

TA貢獻(xiàn)1895條經(jīng)驗(yàn) 獲得超3個(gè)贊

@Blair Conrad說(shuō)在類定義中聲明的靜態(tài)變量,但不在方法內(nèi)部是類或“靜態(tài)”變量:


>>> class Test(object):

...     i = 3

...

>>> Test.i

3

這里有一些問(wèn)題。繼續(xù)上面的例子:


>>> 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__

{}

注意直接設(shè)置t.i屬性時(shí)實(shí)例變量與“static”類變量的同步。這是因?yàn)樵诿臻g內(nèi)重新綁定,這與命名空間不同。如果要更改“靜態(tài)”變量的值,則必須在最初定義它的范圍(或?qū)ο螅﹥?nèi)更改它。我把“靜態(tài)”放在引號(hào)中,因?yàn)镻ython在C ++和Java的意義上并沒有真正的靜態(tài)變量。ititTest


雖然它沒有說(shuō)明有關(guān)靜態(tài)變量或方法的任何內(nèi)容,但Python教程提供了有關(guān)類和類對(duì)象的一些相關(guān)信息。


@Steve Johnson也回答了有關(guān)靜態(tài)方法的問(wèn)題,也在Python Library Reference的“內(nèi)置函數(shù)”中進(jìn)行了介紹。


class Test(object):

    @staticmethod

    def f(arg1, arg2, ...):

        ...

@beid還提到了classmethod,類似于staticmethod。classmethod的第一個(gè)參數(shù)是類對(duì)象。例:


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 the the same as  Test.i = arg1


查看完整回答
反對(duì) 回復(fù) 2019-05-27
?
MM們

TA貢獻(xiàn)1886條經(jīng)驗(yàn) 獲得超2個(gè)贊

靜態(tài)和類方法

正如其他答案所指出的那樣,使用內(nèi)置裝飾器可以輕松完成靜態(tài)和類方法:

class Test(object):

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

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

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

像往常一樣,第一個(gè)參數(shù)MyMethod()綁定到類實(shí)例對(duì)象。與此相反,第一個(gè)參數(shù)MyClassMethod()綁定到類對(duì)象本身(例如,在這種情況下,Test)。因?yàn)?code>MyStaticMethod(),沒有任何參數(shù)被綁定,并且具有參數(shù)是可選的。

“靜態(tài)變量”

然而,實(shí)現(xiàn)“靜態(tài)變量”(好吧,可變的靜態(tài)變量,無(wú)論如何,如果這不是一個(gè)矛盾......)并不是那么簡(jiǎn)單。正如米勒德夫在他的回答中指出的那樣,問(wèn)題在于Python的類屬性并不是真正的“靜態(tài)變量”。考慮:

class Test(object):
    i = 3  # This is a class attributex = Test()x.i = 12   # Attempt to change the value of the 
    class attribute using x instanceassert x.i == Test.i  # ERRORassert Test.i == 3    # Test.i was not affectedassert x.i == 12    
     # x.i is a different object than Test.i

這是因?yàn)樵撔?code>x.i = 12添加了一個(gè)新的實(shí)例屬性i,x而不是更改Testclass i屬性的值。

部分預(yù)期的靜態(tài)變量行為,即多個(gè)實(shí)例之間的屬性同步(但與類本身同步;請(qǐng)參閱下面的“gotcha”),可以通過(guò)將class屬性轉(zhuǎn)換為屬性來(lái)實(shí)現(xiàn):

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)

現(xiàn)在你可以這樣做:

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

現(xiàn)在,靜態(tài)變量將在所有類實(shí)例之間保持同步。

(注意:也就是說(shuō),除非一個(gè)類實(shí)例決定定義它自己的版本_i!但如果某人決定這樣做,他們應(yīng)該得到他們得到的,不是嗎?)

請(qǐng)注意,從技術(shù)上講,i它仍然不是一個(gè)“靜態(tài)變量”; 它是一個(gè)property,它是一種特殊類型的描述符。但是,該property行為現(xiàn)在等同于在所有類實(shí)例中同步的(可變)靜態(tài)變量。

不可變的“靜態(tài)變量”

對(duì)于不可變的靜態(tài)變量行為,只需省略propertysetter:

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)

現(xiàn)在嘗試設(shè)置實(shí)例i屬性將返回AttributeError

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

一個(gè)要意識(shí)到的

需要注意的是,上述方法只適用于工作的情況下,你的類-他們工作,使用類本身時(shí)。例如:

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產(chǎn)生一個(gè)錯(cuò)誤,這是因?yàn)?code>i的屬性Testx是兩個(gè)不同的對(duì)象。

很多人會(huì)發(fā)現(xiàn)這令人驚訝。但是,它不應(yīng)該。如果我們返回并檢查我們的Test類定義(第二個(gè)版本),我們會(huì)注意到這一行:

    i = property(get_i)

顯然,部件iTest必須是一個(gè)property對(duì)象,該對(duì)象是對(duì)象的從返回的類型property的功能。

如果您發(fā)現(xiàn)上述情況令人困惑,您很可能仍會(huì)從其他語(yǔ)言(例如Java或c ++)的角度考慮它。您應(yīng)該研究property對(duì)象,返回Python屬性的返回順序,描述符協(xié)議和方法解析順序(MRO)。

我提出了以下'gotcha'的解決方案; 但是我會(huì)建議 - 強(qiáng)烈地 - 你不要嘗試做以下事情,直到 - 至少 - 你徹底明白為什么assert Test.i = x.i會(huì)導(dǎo)致錯(cuò)誤。

REAL,ACTUAL靜態(tài)變量 -Test.i == x.i

我在下面提供(Python 3)解決方案僅供參考。我并不贊同它是一個(gè)“好的解決方案”。我懷疑是否真的需要在Python中模擬其他語(yǔ)言的靜態(tài)變量行為。但是,無(wú)論它是否真的有用,下面應(yīng)該有助于進(jìn)一步理解Python的工作原理。

更新:這次嘗試非常糟糕 ; 如果你堅(jiān)持做這樣的事情(提示:請(qǐng)不要; Python是一種非常優(yōu)雅的語(yǔ)言,并且只是不需要像其他語(yǔ)言一樣表現(xiàn)出來(lái)),請(qǐng)使用Ethan Furman的答案中的代碼。

使用元類模擬其他語(yǔ)言的靜態(tài)變量行為

元類是類的類。Python中所有類的默認(rèn)元類(即我認(rèn)為的Python 2.3之后的“新風(fēng)格”類)type。例如:

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

但是,您可以像這樣定義自己的元類:

class MyMeta(type): pass

并將其應(yīng)用到您自己的類中(僅限Python 3):

class MyClass(metaclass = MyMeta):
    passtype(MyClass)  # class MyMeta

下面是我創(chuàng)建的元類,它試圖模仿其他語(yǔ)言的“靜態(tài)變量”行為。它基本上可以通過(guò)用版本替換默認(rèn)的getter,setter和deleter來(lái)工作,這些版本檢查所請(qǐng)求的屬性是否是“靜態(tài)變量”。

“靜態(tài)變量”的目錄存儲(chǔ)在StaticVarMeta.statics屬性中。最初嘗試使用替代分辨率順序來(lái)解析所有屬性請(qǐng)求。我把它稱為“靜態(tài)分辨率順序”或“SRO”。這是通過(guò)在給定類(或其父類)的“靜態(tài)變量”集中查找所請(qǐng)求的屬性來(lái)完成的。如果該屬性未出現(xiàn)在“SRO”中,則該類將回退到默認(rèn)屬性get / set / delete行為(即“MRO”)。

from functools import wrapsclass 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


查看完整回答
反對(duì) 回復(fù) 2019-05-27
  • 4 回答
  • 0 關(guān)注
  • 680 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)