Возможны ли статические переменные класса? - PullRequest
1706 голосов
/ 16 сентября 2008

Возможно ли иметь статические переменные класса или методы в python? Какой синтаксис необходим для этого?

Ответы [ 18 ]

5 голосов
/ 21 сентября 2017

Один очень интересный момент в поиске атрибутов Python заключается в том, что его можно использовать для создания « virtual variable»:

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 является статическим в том смысле, что он не связан с конкретным экземпляром, значение все еще зависит от (класса) экземпляра.

4 голосов
/ 22 февраля 2017

Абсолютно Да, Python сам по себе не имеет какого-либо статического члена данных явно, но мы можем получить таким образом

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"
4 голосов
/ 03 июля 2014

В отношении этого ответа для статической переменной constant вы можете использовать дескриптор. Вот пример:

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 выше) не является вашей вещью. Если вы ищете C ++, переменную статического класса в стиле Java:

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

Посмотрите этот ответ и официальные документы HOWTO для получения дополнительной информации о дескрипторах.

3 голосов
/ 17 сентября 2008

Чтобы избежать какой-либо потенциальной путаницы, я бы хотел сопоставить статические переменные и неизменные объекты.

Некоторые примитивные типы объектов, такие как целые числа, числа с плавающей запятой, строки и части, являются неизменяемыми в Python. Это означает, что объект, на который ссылается данное имя, не может измениться, если он относится к одному из вышеупомянутых типов объектов. Имя можно переназначить другому объекту, но сам объект не может быть изменен.

Создание статической переменной делает этот шаг еще дальше, не позволяя имени переменной указывать на любой объект, кроме того, на который она указывает в данный момент. (Примечание: это общая концепция программного обеспечения, а не специфичная для Python; пожалуйста, смотрите посты других для получения информации о реализации статики в Python).

3 голосов
/ 27 февраля 2013

Лучший способ, который я нашел, - это использовать другой класс. Вы можете создать объект, а затем использовать его для других объектов.

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 (Private Static Var).

tryIt класс представляет обычный класс, который нам нужно использовать.

Теперь я сделал объект для одного флага (staticFlag). Этот флаг будет отправлен как ссылка на все обычные объекты.

Все эти объекты добавляются в список tryArr.


Результаты этого скрипта:

False
False
False
False
False
True
True
True
True
True
2 голосов
/ 14 декабря 2018

Да, безусловно, можно писать статические переменные и методы в python.

Статические переменные: Переменная, объявленная на уровне класса, называется статической переменной, к которой можно обращаться напрямую, используя имя класса.

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

Статические методы: Подобно переменным, статические методы могут быть доступны напрямую с помощью класса Name. Не нужно создавать экземпляр.

Но имейте в виду, что статический метод не может вызывать нестатический метод в python.

    >>> class A:
   ...     @staticmethod
   ...     def my_static_method():
   ...             print("Yippey!!")
   ... 
   >>> A.my_static_method()
   Yippey!!
1 голос
/ 01 января 2017

Статические переменные в классе фабрики python3.6

Для тех, кто использует фабрику классов с python3.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
0 голосов
/ 23 мая 2019

Просто создайте класс, который содержит любую переменную или типы объектов. Доступ к этим переменным с помощью класса имя как ниже:


    class StaticVariable:
        myvar1 = 1
        myvar2 = 2


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

...