Возможны ли статические переменные класса в Python?

Файлы cookie не будут полезны для определения уникальных посетителей. Пользователь может очистить файлы cookie и обновить сайт - он снова классифицируется как новый пользователь.

Я думаю, что лучший способ сделать это - реализовать серверное решение (по мере необходимости где-то хранить ваши данные). В зависимости от сложности ваших потребностей для таких данных вам нужно будет определить, что классифицируется как уникальный визит. Разумным методом было бы позволить IP-адресу вернуться на следующий день и получить уникальный визит. Несколько посещений с одного IP-адреса за один день не следует считать уникальными.

Использование PHP, например, тривиально, чтобы получить IP-адрес посетителя и сохранить его в текстовом файле ( или база данных sql).

Решение на стороне сервера будет работать на всех машинах, потому что вы собираетесь отслеживать пользователя, когда он сначала загружает ваш сайт. Не используйте javascript, поскольку это предназначено для сценариев на стороне клиента, плюс пользователь может отключить его в любом случае.

Надеюсь, что это поможет.

1741
задан Georgy 22 June 2019 в 12:09
поделиться

7 ответов

Переменные, объявленные в определении класса, но не в методе, являются переменными класса или статическими переменными:

>>> 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 уже ответил относительно статические методы , также зарегистрировал под , "Встроенные функции" в Справочном руководстве по библиотеке .

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

Python @beidy рекомендуют classmethod с по staticmethod, поскольку метод тогда получает тип класса как первый аргумент, но я все еще немного нечеток на преимуществах этого подхода по staticmethod. Если Вы также, то это, вероятно, не имеет значения.

1717
ответ дан Arne 22 June 2019 в 12:09
поделиться

Для предотвращения любого потенциального беспорядка я хотел бы контрастировать статические переменные и неизменные объекты.

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

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

3
ответ дан Ross 22 June 2019 в 12:09
поделиться

Статические методы в Python называют classmethod с. Смотрите на следующий код

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 использование декоратор @classmethod.

Только для ударов и хихиканья, мы могли звонить myInstanceMethod на классе путем передачи в экземпляре класса, как так:

>>> MyClass.myInstanceMethod(MyClass())
output from an instance method
13
ответ дан Andrii Abramov 22 June 2019 в 12:09
поделиться

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

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

или использование декоратор

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

Для статических свойств.. Его время Вы ищете некоторое определение Python.. переменная может всегда изменяться. Существует два типа их изменяемы и неизменны.. Кроме того, существуют атрибуты класса и атрибуты экземпляра.. Ничто действительно как статические атрибуты в смысле Java & C++

, Почему статический метод использования в смысле pythonic, если это не имеет никакого отношения вообще к классу! На вашем месте я или использовал бы classmethod или определил бы метод, независимый от класса.

15
ответ дан emb 22 June 2019 в 12:09
поделиться

Можно также добавить переменные класса к классам на лету

>>> 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]
25
ответ дан Ned Batchelder 22 June 2019 в 12:09
поделиться

@Blair Conrad сказал статические переменные, объявленные в определении класса, но не в методе, являются классом или "статическими" переменными:

>>> 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 пространство имен. Если Вы хотите изменить значение "статической" переменной, необходимо изменить его в объеме (или объект), где оно было первоначально определено. Я поместил "статичный" в кавычки, потому что Python действительно не имеет статических переменных в том смысле, что C++ и Java делают.

, Хотя это не говорит ничего определенного относительно статических переменных или методов, , учебное руководство Python имеет немного релевантной информации о [1 111] классы и объекты класса .

@Steve Johnson также ответил относительно статических методов, также зарегистрированных под "Встроенными функциями" в Справочное руководство по библиотеке Python.

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

@beid также упомянул 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 the the same as  Test.i = arg1

Pictorial Representation Of Above Example

569
ответ дан Jarvis 22 June 2019 в 12:09
поделиться

Можно использовать список или словарь для получения "статического поведения" между экземплярами.

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
ответ дан 22 November 2019 в 20:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: