Можно ли в Python иметь статические переменные или методы класса? Какой синтаксис необходим для этого?
Переменные, объявленные внутри определения класса, но не внутри метода, являются переменными класса или статическими переменными:
>>> class MyClass:
... i = 3
...
>>> MyClass.i
3
Как отмечает @millerdev, это создает переменную i
на уровне класса, но она отличается от любой переменной i
на уровне экземпляра, так что вы можете иметь
>>> m = MyClass()
>>> m.i = 4
>>> MyClass.i, m.i
>>> (3, 4)
Это отличается от C++ и Java, но не так сильно отличается от C#, где к статическому члену нельзя получить доступ, используя ссылку на экземпляр.
Смотрите что говорит учебник по Python на тему классов и объектов классов.
@Steve Johnson уже ответил по поводу статических методов, также документированных в разделе "Встроенные функции" в Python Library Reference.
class C:
@staticmethod
def f(arg1, arg2, ...): ...
@beidy рекомендует classmethods вместо staticmethod, так как метод получает тип класса в качестве первого аргумента, но я все еще не совсем понимаю преимущества этого подхода перед staticmethod. Если вы тоже, то это, вероятно, не имеет значения.
@Блэр Конрад сказал, что статические переменные, объявленные внутри определения класса, но не внутри метода класса или "статический" и переменные:
>>> class Test(object):
... i = 3
...
>>> Test.i
3
Есть несколько Гоча's здесь. Продолжая приведенный выше пример:
>>> 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__
{}
Обратите внимание, как переменная экземпляра Т.я вышел из синхронизации с помощью "статический" в переменной класса, когда атрибут " я "был установлен прямо на "Т". Это потому, что " я " была заново переплетена в
Т` пространства имен, который отличается от тест имен. Если вы хотите изменить значение а "статический" и переменной, вы должны изменить его в рамках (или объекта), где он был изначально определен. Я поставил на "статический" в кавычках, потому что питон на самом деле не имеет статических переменных в том смысле, что C++ и Java сделать.
Хотя это вовсе'т сказать ничего конкретного о статических переменных или методов, питон учебник имеет некоторые соответствующую информацию на классы и объекты класс.
Стив @Джонсон также ответил по поводу статических методов, также оформленными в соответствии с "встроенные функции" в библиотеке Python справочник.
class Test(object):
@staticmethod
def f(arg1, arg2, ...):
...
@бейдом также отметил classmethod в, который похож на staticmethod. А classmethod в'первым аргументом является объект класса. Пример:
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
Как я уже отметил, статические и методов класса легко выполняется с помощью встроенного декораторов:
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 () - это связано с классом самого объекта (например, в данном случае "тест"). Для MyStaticMethod (), ни один из аргументов связан, и имея аргументов вообще не является обязательным.
Однако реализация "и статических переменных и" (Ну, Мутабельный статические переменные, все равно, если это's не противоречие в терминах...) не так прямо вперед. Как millerdev указал в своем ответе, Проблема в том, что Python'атрибуты класса S Не действительно"и статические переменные " и;. Рассмотрим:
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
Это происходит потому, что строка х.я = 12
добавил новый экземпляр атрибута я
на Х
вместо изменения значения класса test
я` атрибут.
Частичная ожидаемые статические переменные поведение, т. е. синхронизацию атрибутов между несколькими экземплярами (но не с классом самого себя; увидеть "не понял" и ниже), может быть достигнуто путем поворота атрибута class в собственность:
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
Статическая переменная будет оставаться в синхронизации между все экземпляры класса.
(Примечание: то есть, если экземпляр класса решает определить свою собственную версию я
! Но если кто-то решит сделать это, они заслуживают то, что получают, Дон't они???)
Обратите внимание, что с технической точки зрения, " я "еще не 'статическую переменную' на всех; это "имущество", представляющего собой особый тип описателя. Однако, собственность
поведение эквивалентно (изменяемый) статической переменной синхронизируются между всеми экземплярами класса.
Для неизменных статических переменных поведения, просто опустить собственность
сеттер:
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)
Теперь при попытке установить экземпляр я
атрибут возвращает 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'
Утверждают, проверить линию.я == х.у меня выдает ошибку, потому что я
атрибут тест
и X
являются двумя разными объектами.
Многие люди найдут в этом удивительного. Однако, это не должно быть. Если мы вернемся и проверить наш "тест" определение класса (вторая версия), мы отмечаем эту строку:
i = property(get_i)
Очевидно, что члены " я ""тест" должен быть "имущество" объекта, который является тип объекта, возвращаемого из функции собственность
.
Если вы найдете выше заблуждение, вы, скорее всего, до сих пор думаю об этом с точки зрения других языков (например, Java или C++). Вы должны проходить обучение в "имущество" объекта, о порядке, в котором атрибуты в Python возвращаются, протокола дескриптора, и метод резолюции заказа (МРО).
Я представляю решение вышеназванных 'попался' ниже; однако я хотел бы предложить, - усиленно - что вы не пытаетесь делать нечто вроде следующего, пока - как минимум - вы хорошо понимаете, почему утверждают теста.я = х.я` приводит к ошибке.
Я представляю решение (в Python 3) ниже только для ознакомительных целей. Я не одобряю его как-то "хорошее решение" по. У меня есть сомнения в том, что эмуляция статическую переменную поведение других языках, в Python-это на самом деле необходимо. Однако, независимо от того, является ли это на самом деле полезно, указанных ниже, должны помочь дальнейшему пониманию того, как работает Python. Обновление: эта попытка это ужасно; если вы настаиваете на делать что-то вроде этого (подсказка: пожалуйста, Дон'т; Python-это очень элегантный язык и обуви Хорнинг его в себя, как другой язык просто не нужен), использовать код в Итан Фурман'ы ответ вместо этого. Эмулировать статические переменные поведение других языков с помощью метакласса В метакласс-это класс классов. Метакласс по умолчанию для всех классов в Python (т. е. в "Новый Стиль" и классы поста питона 2.3 я считаю) - это "тип". Например:
type(int) # class 'type'
type(str) # class 'type'
class Test(): pass
type(Test) # class 'type'
Однако, вы можете определить свой собственный метакласс такой:
class MyMeta(type): pass
И применить его на свой собственный класс, как это (в Python 3 только):
class MyClass(metaclass = MyMeta):
pass
type(MyClass) # class MyMeta
Ниже находится метакласс я создал, который пытается эмулировать "и статическую переменную" и поведение других языках. Она в основном работает путем замены по умолчанию геттер, сеттер и deleter с версиями, которые проверяют, чтобы увидеть, если запрашивается атрибут и "статическую переменную и". Каталог "и статические переменные", которая хранится в StaticVarMeta.атрибут статика`. Все запросы атрибут изначально пытался быть решены с помощью замены приказа. Я бы назвал это "и статический порядок разрешения и", или "партнерство" и. Это делается путем ищет запрошенный атрибут в наборе "и статические переменные, что" для данного класса (или его родительских классов). Если атрибут не отображается в "партнерство" в класс вернется на атрибут по умолчанию сделать/установить/удалить поведение (т. е. на "МРО и").
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
Вы также можете добавить переменные класса классов на лету
>>> 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]
Лично я использовал бы метод класса всегда, когда мне нужен статический метод. В основном потому, что в качестве аргумента я получаю класс.
class myObj(object):
def myMethod(cls)
...
myMethod = classmethod(myMethod)
или использовать декоратор
class myObj(object):
@classmethod
def myMethod(cls)
Для статических свойств... Пришло время посмотреть определение в Python. Переменная всегда может меняться. Они бывают двух типов - изменяемые и неизменяемые. Также есть атрибуты класса и атрибуты экземпляра. Ничего похожего на статические атрибуты в смысле java & c++.
Зачем использовать статический метод в питоническом смысле, если он не имеет никакого отношения к классу! На вашем месте я бы либо использовал classmethod, либо определил метод независимо от класса.
Статические методы в python называются classmethods. Взгляните на следующий код
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
Обратите внимание, что когда мы вызываем метод myInstanceMethod, мы получаем ошибку. Это происходит потому, что метод должен быть вызван на экземпляре этого класса. Метод myStaticMethod установлен как метод класса с помощью декоратора @classmethod.
Просто для прикола, мы можем вызвать myInstanceMethod на классе, передав экземпляр класса, как показано ниже:
>>> MyClass.myInstanceMethod(MyClass())
вывод метода экземпляра
Одна специальная вещь, чтобы отметить о статическом &амп свойства; свойства экземпляра, как показано в примере ниже:
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
Это означает, что перед тем, как присвоить значение в свойство экземпляра, если мы попытаемся получить доступ к свойству через' экземпляр используется статическое значение. Каждое свойство объявлено в Python класс всегда имеет статический слот в памяти.
Когда определимся с переменной-члена вне любой метод члена, переменная может быть статическим или нестатическим в зависимости от того, как переменная выражена.
Например:
#!/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
Один очень интересный момент о Python'ы атрибут поиска является то, что он может быть использован для создания "Виртуальный переменные и":
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!
Обычно там ничего'т все задания к этим после того, как они создаются. Обратите внимание, что "уточняющий запрос" использует "я", потому что, хотя метка
является статическим в том смысле, что не связан с экземпляром particular, стоимость еще зависит от (класс) экземпляра.
Вы также можете применить класс статический, используя метакласс.
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
Потом, когда случайно вы пытаетесь инициализировать класса MyClass вы'МР получить StaticClassError.
Можно иметь статический
переменные класса, но, вероятно, не стоит усилий.
Здесь'ы доказательство концепции, написанный на Python 3 -- Если какие-либо точные данные ошибочны код может быть изменен, чтобы соответствовать примерно то, что вы имеете в виду под статической переменной:
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
Абсолютно Да Питон сам по себе Дон'Т есть какие-либо статические данные-члены явно, но мы можем делать так
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"
В связи с этим ответ, на постоянное статическую переменную, вы можете использовать дескриптор. Здесь'ы пример:
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
Вы всегда можете поднять исключение, если спокойно игнорирует значение (перевал
выше) это не ваша вещь. Если вы'вновь ищет с++, 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
Взгляните на этот ответ и официальных документах методические указания для получения дополнительной информации о дескрипторах.
Чтобы избежать любых возможных недоразумений, я хотел бы, чтобы контраст статические переменные и неизменные объекты.
Некоторые примитивные типы объектов, такие как целые числа, поплавки, канаты, и touples являются неизменными в Python. Это означает, что объект, на который ссылается данное имя не может измениться, если это кого-либо из перечисленных типов объектов. Имя может быть переведен на другой объект, но сам объект не может быть изменен.
Делая переменную статической, пошел еще дальше, запретив имя переменной, чтобы указать на любой объект, но то, что в настоящее время точками. (Примечание: это общая концепция программного обеспечения, а не конкретные на Python; пожалуйста, см. Другие' должности, информацию о внедрении статики в Python).
Да, наверняка можно написать статические переменные и методы в 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
Статические методы: похожи на переменные, статические методы могут быть доступны непосредственно через имя класса. Не нужно создавать экземпляр.
Но имейте в виду, что статический метод не может вызвать нестатический метод в Python.
>>> class A:
... @staticmethod
... def my_static_method():
... print("Yippey!!")
...
>>> A.my_static_method()
Yippey!!
Лучший способ я нашел, чтобы использовать другой класс. Вы можете создать объект и затем использовать его на других объектах.
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
.
Этот класс должен представить статические тиристорные __успех
(частная статические тиристорные).
tryIt
класса представляли тот класс, который мы должны использовать.
Теперь я сделал объект на один флаг (staticFlag
). Этот флаг будет отправлен как ссылка на все обычные объекты.
Все эти объекты добавляются в список tryArr
.
Этот Скрипт Результаты:
False
False
False
False
False
True
True
True
True
True
Для тех, кто с помощью фабрики классов с питон3.6 и использовать "нелокального" сайта, чтобы добавить его в рамки контекста класса создается следующим образом:
>>> 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
Вы можете использовать список или словарь, чтобы получить "и статическое поведение" и между экземплярами.
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