Domanda

È possibile avere una classe statica variabili o metodi in python?Cosa sintassi è richiesto per fare questo?

È stato utile?

Soluzione

Le variabili dichiarate all'interno della definizione della classe, ma non all'interno di un metodo di classe o variabili statiche:

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

Come @millerdev sottolinea, questo crea un livello di classe i variabile, ma questo è diverso da qualsiasi livello di istanza i variabile, in modo che si potrebbe avere

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

Questo è diverso dal C++ e Java, ma non è così diversa da C#, dove un membro statico non può essere eseguito utilizzando un riferimento a un'istanza.

Vedere ciò che il Python tutorial ha da dire in tema di classi e oggetti di classe.

@Steve Johnson ha già risposto per quanto riguarda i metodi statici, anche documentato sotto "Le Funzioni Built-in" in Libreria Python Riferimento.

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

@beidy consiglia classmethods oltre staticmethod, come il metodo riceve quindi il tipo di classe, come primo argomento, ma io sono ancora un po ' confuso sui vantaggi di questo approccio rispetto staticmethod.Se si, allora probabilmente non importa.

Altri suggerimenti

@Blair Conrad ha detto statica variabili dichiarate all'interno della definizione della classe, ma non all'interno di un metodo di classe o "statico" variabili:

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

Ci sono un paio di gotcha qui.Portando l'esempio di cui sopra:

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

Notare come la variabile di istanza t.i ha sincronizzato con il "statico" variabile di classe quando l'attributo i è situato direttamente sul t.Questo è perché i è stato re-bound entro il t spazio dei nomi, che è distinto dal Test spazio dei nomi.Se si desidera modificare il valore di una "statica" variabile, si deve cambiare entro la portata (o un oggetto) in cui è stato originariamente definito.Ho messo "statico" tra virgolette perché Python non hanno davvero le variabili statiche, nel senso che il C++ e Java fare.

Anche se non dice nulla di specifico su di variabili statiche o i metodi, i Python tutorial ha alcune importanti informazioni su classi e oggetti di classe.

@Steve Johnson anche risposto per quanto riguarda i metodi statici, documentati anche in "Funzioni Built-in" in Libreria Python di Riferimento.

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

@beid anche detto classmethod, che è simile a staticmethod.Un classmethod primo argomento è l'oggetto di classe.Esempio:

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

Pictorial Representation Of Above Example

Statica e Metodi di Classe

Come le altre risposte hanno notato, statico e i metodi della classe sono facilmente realizzato utilizzando il built-in e decoratori:

class Test(object):

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

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

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

Come di consueto, il primo argomento MyMethod() è associato alla classe oggetto di istanza.In contrasto, il primo argomento MyClassMethod() è associato alla classe oggetto stesso (ad esempio, in questo caso, Test).Per MyStaticMethod(), nessuno degli argomenti sono legati, e avendo argomenti a tutti è facoltativo.

"Le Variabili Statiche"

Tuttavia, l'attuazione di "variabili statiche" (beh, mutevole le variabili statiche, in ogni caso, se non è una contraddizione in termini...), non è così semplice.Come millerdev ha sottolineato nella sua risposta, il problema è che Python attributi della classe non sono veramente "variabili statiche".Prendere in considerazione:

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

Questo è perché la linea x.i = 12 ha aggiunto una nuova istanza attributo i per x invece di cambiare il valore della Test classe i attributo.

Parziale previsto variabile statica comportamento, per esempio, la sincronizzazione dell'attributo tra più istanze (ma non con la classe stessa;vedere "gotcha" di seguito), può essere ottenuto ruotando l'attributo di classe in una proprietà:

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)

Ora si può fare:

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

La variabile statica rimarrà ora in sync tra tutte le istanze della classe.

(NOTA:Che è, a meno che un'istanza di classe decide di definire la propria versione di _i!Ma se qualcuno decide di farlo, si meritano ciò che hanno ottenuto, non è così???)

Nota che, tecnicamente parlando, i non è ancora una 'variabile statica' a tutti;si tratta di un property, che è un particolare tipo di descrittore.Tuttavia, l' property il comportamento è ora pari ad un (mutevole) variabile statica sincronizzati in tutte le istanze della classe.

Immutabile "Variabili Statiche"

Per immutabile, statico comportamento delle variabili, è sufficiente omettere il property setter:

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)

Ora sta tentando di impostare l'istanza i attributo di restituire un AttributeError:

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

Una Nota per essere a Conoscenza di

Si noti che i metodi di cui sopra funziona solo con le istanze di classe - che sarà non lavoro quando si utilizza la classe stessa.Così, per esempio:

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'

La linea assert Test.i == x.i produce un errore, perché il i attributo di Test e x sono due oggetti diversi.

Molte persone trovano questo sorprendente.Tuttavia, non deve essere.Se andiamo indietro e ispezionare il nostro Test definizione di classe (la seconda versione), prendiamo nota di questa riga:

    i = property(get_i) 

Chiaramente, gli stati i di Test deve essere un property oggetto, che è il tipo di oggetto restituito dalla property funzione.

Se si trova al di sopra di confusione, è più probabile ancora pensando su di esso dal punto di vista di altre lingue (es.Java o c++).Si dovrebbe andare a studiare il property oggetto, sull'ordine in cui Python attributi vengono restituiti, il descrittore di protocollo, e il metodo di risoluzione ordine (MRO).

Vi presento una soluzione al di sopra 'gotcha' sotto;tuttavia vorrei suggerire - con insistenza - che non si tenta di fare qualcosa di simile fino a quando, come minimo, ti permette di capire perché assert Test.i = x.i causa un errore.

REALE, EFFETTIVO Variabili Statiche - Test.i == x.i

Ho presente l' (Python 3) soluzione sotto solo a scopo informativo.Io non sono girata come una "buona soluzione".Ho i miei dubbi che emula la variabile statica comportamento di altre lingue in Python è mai realmente necessario.Tuttavia, a prescindere se sia effettivamente utile, il seguente dovrebbe aiutare ulteriormente la comprensione di come Python funziona.

AGGIORNAMENTO:questo tentativo è veramente terribile;se ti ostini a fare qualcosa di simile a questo (suggerimento:si prega di non;Python è un molto elegante lingua e scarpe horning è in grado di comportarsi come un'altra lingua non è necessario), utilizzare il codice Ethan Furman risposta invece.

Emulando variabile statica comportamento di altre lingue utilizzando una metaclass

Una metaclass è la classe di una classe.L'impostazione predefinita metaclass per tutte le classi in Python (cioè, il "nuovo stile" classi post Python 2.3 credo) è type.Per esempio:

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

Tuttavia, è possibile definire i propri metaclass come questo:

class MyMeta(type): pass

E applicarlo alla tua classe (Python 3):

class MyClass(metaclass = MyMeta):
    pass

type(MyClass)  # class MyMeta

Qui di seguito è una metaclass ho creato, che tenta di emulare il "variabile statica" il comportamento di altre lingue.Funziona praticamente da sostituire getter, setter, e deleter con le versioni che controllare per vedere se l'attributo richiesto è una "variabile statica".

Un catalogo delle "variabili statiche" viene memorizzato nel StaticVarMeta.statics attributo.Tutti attributo richieste sono inizialmente ha tentato di risolvere utilizzando un sostituto ordine di risoluzione.Ho chiamato questa la "statica ordine di risoluzione", o "SRO".Questo viene fatto cercando l'attributo richiesto, nella serie di "variabili statiche" per una determinata classe (o della sua controllante classi).Se l'attributo non viene visualizzato nel "SRO", la classe si rifarà l'attributo predefinito get/set/comportamento di eliminazione (cioè, "MRO").

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

È inoltre possibile aggiungere variabili di classe per le classi al volo

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

E classe di istanze, è possibile modificare le variabili di classe

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

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

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

Personalmente, io uso un classmethod ogni volta che ho bisogno di un metodo statico.Soprattutto perché ho la classe come argomento.

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

o utilizzare un decoratore

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

Per le proprietà statiche..Il suo tempo è di leggere alcuni python definizione..variabile può sempre cambiare.Ci sono due tipi di mutabili e immutabili..Inoltre, ci sono gli attributi di classe e gli attributi dell'istanza..In realtà, niente di come attributi statici, nel senso di java e c++

Perché utilizzare il metodo statico in divinatori senso, se non ha alcuna relazione con qualsiasi cosa per la classe di!Se fossi in te, mi piacerebbe utilizzare classmethod o definire il metodo indipendente dalla classe.

Uno speciale per la nota sulla statica proprietà e le proprietà di istanza, mostrato nell'esempio qui sotto:

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

Questo significa che prima di assegnare il valore alla proprietà di istanza, se si tenta di accedere alla proprietà al' istanza, il valore statico viene utilizzato. Ogni proprietà ha dichiarato in python classe ha sempre statico slot di memoria.

I metodi statici in python sono chiamati classmethods.Date un'occhiata al il seguente codice

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

Si noti che quando si chiama il metodo myInstanceMethod, si ottiene un errore.Questo è perché richiede che il metodo di essere chiamato su un'istanza di questa classe.Il metodo myStaticMethod è impostato come un classmethod utilizzando il decoratore @classmethod.

Solo per i calci e le risatine, che si potrebbe chiamare myInstanceMethod in classe, passando in un'istanza della classe, in questo modo:

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

Quando la definizione di alcune variabili membro al di fuori di qualsiasi membro del metodo, la variabile può essere statico o non statico a seconda di come la variabile è espressa.

  • CLASSNAME.il var è variabile statica
  • INSTANCENAME.var non è variabile statica.
  • auto.var all'interno della classe non è variabile statica.
  • var all'interno della funzione membro della classe non è definito.

Per esempio:

#!/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()

I risultati sono

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

Si potrebbe anche applicare una classe statica utilizzando metaclass.

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

Quindi ogni volta che per caso si tenta di inizializzare MyClass si otterrà un StaticClassError.

È possibile avere static variabili di classe, ma probabilmente non vale la pena.

Ecco un proof-of-concept scritto in Python 3-se uno qualsiasi dei dettagli esatti sono sbagliato il codice può essere modificato per corrispondere solo su ciò che si intende per una 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)

e / o in uso:

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

e alcuni test:

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

Un punto interessante su Python attributo di ricerca è che può essere utilizzato per creare "virtuale le variabili":

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!

Normalmente non ci sono assegnazioni di questi dopo averli creati.Si noti che la ricerca utilizza self perché, anche se label è statico, nel senso di non essere associato con un particolare esempio, il valore dipende ancora dalla (classe i) istanza.

In riferimento a questa risposta, per un costante variabile statica, è possibile utilizzare un descrittore.Ecco un esempio:

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

con conseguente ...

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

Si può sempre sollevare un'eccezione se in silenzio, ignorando il valore di impostazione (pass sopra) non è la vostra cosa.Se stai cercando un C++, Java stile statico variabile di classe:

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

Guarda questa risposta e la documentazione ufficiale HOWTO per ulteriori informazioni sui descrittori.

Assolutamente Sì, Python di per sé non hanno alcun membro statico in modo esplicito, ma Si può avere così facendo

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

uscita

0
0
1
1

spiegazione

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

Per evitare ogni possibile confusione, vorrei contrasto statico di variabili e oggetti immutabili.

Primitivi di tipi di oggetti come gli interi, i carri, le stringhe, e touples sono immutabili in Python.Questo significa che l'oggetto è definito da un nome non può cambiare se si tratta di uno dei suddetti tipi di oggetto.Il nome può essere riassegnato ad un altro oggetto, ma l'oggetto non può essere modificato.

Facendo una variabile statica prende questo un ulteriore passo avanti consentendo il nome della variabile da punto a qualsiasi oggetto, ma ciò a cui attualmente punti.(Nota:questo è un generale concetto di software e non di Python;si prega di vedere i post altrui per informazioni sull'implementazione statica in Python).

Il modo migliore che ho trovato è quello di utilizzare un'altra classe.È possibile creare un oggetto e poi lo uso su altri oggetti.

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

Con l'esempio di cui sopra, ho fatto una classe denominata staticFlag.

Questa classe devono presentare la static var __success (Private Static Var).

tryIt classe rappresentata la classe regolare che dobbiamo utilizzare.

Ora ho fatto un oggetto per una bandierastaticFlag).Questa bandiera dovrà essere inviato come riferimento per tutti gli oggetti normali.

Tutti questi oggetti sono stati aggiunti alla lista tryArr.


Questo Script Risultati:

False
False
False
False
False
True
True
True
True
True

Sì, sicuramente, la possibilità di scrivere le variabili statiche e metodi in python.

Variabili Statiche : Variabile dichiarata a livello di classe sono chiamati variabile statica a cui si può accedere direttamente utilizzando il nome della classe.

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

    >>> print(A.my_var)
        shagun

Le variabili di istanza: Le variabili sono correlate e vi si accede da istanza di una classe sono le variabili di istanza.

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

I Metodi Statici: Come le variabili, i metodi statici possono essere accessibili direttamente tramite Nome della classe.Non c'è bisogno di creare un'istanza.

Ma tenere a mente, un metodo statico non può chiamare un metodo non statico in python.

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

Le Variabili statiche Classe di fabbrica python3.6

Per chiunque l'utilizzo di una classe di fabbrica con python3.6 e utilizzare il nonlocal parola chiave per aggiungere l'ambito / contesto di classe venga creata in questo modo:

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

È sufficiente creare una classe che contiene una qualunque variabile o tipi di oggetti.Accesso variabili mediante la classe nome come di seguito:


    class StaticVariable:
        myvar1 = 1
        myvar2 = 2


    StaticVariable.myvar1 = StaticVariable.myvar1 +1
    StaticVariable.myvar2 = StaticVariable.myvar2 +1

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top