Как мне создать константу в Python?

Вы можете выполнить rtrim() в строке в начале каждой итерации цикла.

function getProductCount($path)
{
    $count = 0;

    foreach (file($path) as $raw_name) {
        $name = rtrim($raw_name);
        if($name == "")
        {
            $count = $count + 1;
        }
    }
    return $count;
}

854
задан Stevoisiak 21 August 2017 в 14:52
поделиться

6 ответов

Нет, нет. Вы не можете объявить переменную или значение как константу в Python. Только не меняй это.

Если вы находитесь в классе, эквивалентом будет:

class Foo(object):
    CONST_NAME = "Name"

если нет, то просто

CONST_NAME = "Name"

Но вы, возможно, захотите взглянуть на фрагмент кода Константы в Python от Alex Мартелли.


Начиная с Python 3.8, существует аннотация переменной typing.Final , которая сообщит средствам проверки статических типов (например, mypy), что ваша переменная не должна быть переназначена. Это ближайший эквивалент Java final . Однако он на самом деле не предотвращает переназначение :

from typing import Final

a: Final = 1

# Executes fine, but mypy will report an error if you run mypy on this:
a = 2
882
ответ дан 22 November 2019 в 21:03
поделиться

PEP 591 имеет 'заключительный' спецификатор. Осуществление до средства проверки типа.

, Таким образом, можно сделать:

MY_CONSTANT: Final = 12407
4
ответ дан 22 November 2019 в 21:03
поделиться

В Python вместо того, чтобы что-то навязывать языку, люди используют соглашения об именах, например __ method для частных методов и использование _method для защищенных методов.

Таким же образом вы можете просто объявить константу заглавными буквами, например

MY_CONSTANT = "one"

Если вы хотите, чтобы эта константа никогда не менялась, вы можете подключиться к доступу к атрибутам и проделать трюки, но более простой подход - объявить функцию

def MY_CONSTANT():
    return "one"

Проблема только в том, что везде вам придется выполнять MY_CONSTANT (), но опять же MY_CONSTANT = "one" - правильный путь в python (обычно).

Вы также можете использовать namedtuple для создания констант:

>>> from collections import namedtuple
>>> Constants = namedtuple('Constants', ['pi', 'e'])
>>> constants = Constants(3.14, 2.718)
>>> constants.pi
3.14
>>> constants.pi = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
103
ответ дан 22 November 2019 в 21:03
поделиться

Пифонический способ объявления «констант» - это, по сути, переменная уровня модуля:

RED = 1
GREEN = 2
BLUE = 3

А затем напишите свои классы или функции. Поскольку константы почти всегда являются целыми числами, и они также неизменны в Python, у вас очень мало шансов изменить их.

Если, конечно, вы явно не установили RED = 2 .

4
ответ дан 22 November 2019 в 21:03
поделиться

Нет ключевого слова const , как в других языках, однако можно создать свойство, которое имеет «функцию получения» для чтения данных, но нет » функция установки " для перезаписи данных. Это существенно защищает идентификатор от изменения.

Вот альтернативная реализация, использующая свойство класса:

Обратите внимание, что код далеко не прост для читателя, интересующегося константами. См. Объяснение ниже

def constant(f):
    def fset(self, value):
        raise TypeError
    def fget(self):
        return f()
    return property(fget, fset)

class _Const(object):
    @constant
    def FOO():
        return 0xBAADFACE
    @constant
    def BAR():
        return 0xDEADBEEF

CONST = _Const()

print CONST.FOO
##3131964110

CONST.FOO = 0
##Traceback (most recent call last):
##    ...
##    CONST.FOO = 0
##TypeError: None

Пояснение кода:

  1. Определите функцию константу , которая принимает выражение и использует его для создания «получателя» - функции, которая только возвращает значение выражения.
  2. Функция установки вызывает ошибку TypeError, поэтому она доступна только для чтения
  3. Используйте только что созданную функцию константы в качестве украшения, чтобы быстро определить свойства, доступные только для чтения.

И другим, более старомодным способом:

(Код довольно сложен, подробности ниже)

class _Const(object):
    @apply
    def FOO():
        def fset(self, value):
            raise TypeError
        def fget(self):
            return 0xBAADFACE
        return property(**locals())

CONST = _Const()

print CONST.FOO
##3131964110

CONST.FOO = 0
##Traceback (most recent call last):
##    ...
##    CONST.FOO = 0
##TypeError: None

Обратите внимание, что декоратор @apply, кажется, устарел.

  1. Чтобы определить идентификатор FOO, сначала нужно определить две функции (fset, fget - имена на мой выбор).
  2. Затем используйте встроенную функцию property для создания объекта, который можно «установить» или «получить».
  3. Обратите внимание, что первые два параметра функции свойства называются fset и fget .
  4. Воспользуйтесь тем фактом, что мы выбрали именно эти имена для нашего собственного геттера и сеттера, и создайте словарь ключевых слов, используя ** (двойная звездочка), примененный ко всем локальным определениям этой области, чтобы передать параметры свойству function
337
ответ дан 22 November 2019 в 21:03
поделиться

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

я знаю, что использование константы не является pythonic, и Вы не должны делать этого дома!

Однако Python является таким динамическим языком! Этот форум показывает, как это возможно создание конструкций это стили как константы. Этот ответ имеет как основная цель для исследования то, что может быть выражено языком.

не будьте слишком резки со мной :-).

для получения дополнительной информации я записал блог сопровождения об этих идиомах .

В этом сообщении, я назову постоянную переменную к постоянной ссылке на значения (неизменной или иначе). Кроме того, я говорю, что переменная имеет замороженное значение, когда она ссылается на изменяемый объект, что клиентский код не может обновить свое значение (значения).

пространство А констант (SpaceConstants)

Эта идиома создает то, что похоже на пространство имен постоянных переменных (иначе SpaceConstants). Это - модификация фрагмента кода Alex Martelli для предотвращения использования объектов модуля. В частности, эта модификация использует то, что я называю фабрикой классов, потому что в [1 131] функция SpaceConstants, класс, названный , SpaceConstants определяется, и экземпляр его возвращается.

я исследовал использование фабрики классов для реализации основанного на политике двойника дизайна в Python в stackoverflow и также в сообщение в блоге .

def SpaceConstants():
    def setattr(self, name, value):
        if hasattr(self, name):
            raise AttributeError(
                "Cannot reassign members"
            )
        self.__dict__[name] = value
    cls = type('SpaceConstants', (), {
        '__setattr__': setattr
    })
    return cls()

sc = SpaceConstants()

print(sc.x) # raise "AttributeError: 'SpaceConstants' object has no attribute 'x'"
sc.x = 2 # bind attribute x
print(sc.x) # print "2"
sc.x = 3 # raise "AttributeError: Cannot reassign members"
sc.y = {'name': 'y', 'value': 2} # bind attribute y
print(sc.y) # print "{'name': 'y', 'value': 2}"
sc.y['name'] = 'yprime' # mutable object can be changed
print(sc.y) # print "{'name': 'yprime', 'value': 2}"
sc.y = {} # raise "AttributeError: Cannot reassign members"

пространство А замороженных значений (SpaceFrozenValues)

Эта следующая идиома является модификацией , SpaceConstants в, где ссылается изменяемых объектах замораживается. Эта реализация использует то, что я называю совместно использованное закрытие между [1 134] setattr и функции getattr. Значение изменяемого объекта скопировано и сослано переменной , кэш определяет в совместно использованном закрытии функции. Это формирует то, что я называю , закрытие защитило копию изменяемого объекта .

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

from copy import deepcopy

def SpaceFrozenValues():
    cache = {}
    def setattr(self, name, value):
        nonlocal cache
        if name in cache:
            raise AttributeError(
                "Cannot reassign members"
            )
        cache[name] = deepcopy(value)
    def getattr(self, name):
        nonlocal cache
        if name not in cache:
            raise AttributeError(
                "Object has no attribute '{}'".format(name)
            )
        return deepcopy(cache[name])
    cls = type('SpaceFrozenValues', (),{
        '__getattr__': getattr,
        '__setattr__': setattr
    })
    return cls()

fv = SpaceFrozenValues()
print(fv.x) # AttributeError: Object has no attribute 'x'
fv.x = 2 # bind attribute x
print(fv.x) # print "2"
fv.x = 3 # raise "AttributeError: Cannot reassign members"
fv.y = {'name': 'y', 'value': 2} # bind attribute y
print(fv.y) # print "{'name': 'y', 'value': 2}"
fv.y['name'] = 'yprime' # you can try to change mutable objects
print(fv.y) # print "{'name': 'y', 'value': 2}"
fv.y = {} # raise "AttributeError: Cannot reassign members"

А постоянное пространство (ConstantSpace)

Эта идиома является неизменным пространством имен постоянных переменных или ConstantSpace. Это - комбинация удивительно ответа простого Jon Betts в [1 110] stackoverflow с фабрика классов .

def ConstantSpace(**args):
    args['__slots__'] = ()
    cls = type('ConstantSpace', (), args)
    return cls()

cs = ConstantSpace(
    x = 2,
    y = {'name': 'y', 'value': 2}
)

print(cs.x) # print "2"
cs.x = 3 # raise "AttributeError: 'ConstantSpace' object attribute 'x' is read-only"
print(cs.y) # print "{'name': 'y', 'value': 2}"
cs.y['name'] = 'yprime' # mutable object can be changed
print(cs.y) # print "{'name': 'yprime', 'value': 2}"
cs.y = {} # raise "AttributeError: 'ConstantSpace' object attribute 'x' is read-only"
cs.z = 3 # raise "AttributeError: 'ConstantSpace' object has no attribute 'z'"

А замороженное пространство (FrozenSpace)

Эта идиома является неизменным пространством имен замороженных переменных или FrozenSpace. Это получено из предыдущего шаблона путем создания каждой переменной защищенное свойство закрытием из сгенерированных класс FrozenSpace .

from copy import deepcopy

def FreezeProperty(value):
    cache = deepcopy(value)
    return property(
        lambda self: deepcopy(cache)
    )

def FrozenSpace(**args):
    args = {k: FreezeProperty(v) for k, v in args.items()}
    args['__slots__'] = ()
    cls = type('FrozenSpace', (), args)
    return cls()

fs = FrozenSpace(
    x = 2,
    y = {'name': 'y', 'value': 2}
)

print(fs.x) # print "2"
fs.x = 3 # raise "AttributeError: 'FrozenSpace' object attribute 'x' is read-only"
print(fs.y) # print "{'name': 'y', 'value': 2}"
fs.y['name'] = 'yprime' # try to change mutable object
print(fs.y) # print "{'name': 'y', 'value': 2}"
fs.y = {} # raise "AttributeError: 'FrozenSpace' object attribute 'x' is read-only"
fs.z = 3 # raise "AttributeError: 'FrozenSpace' object has no attribute 'z'"
1
ответ дан 22 November 2019 в 21:03
поделиться
Другие вопросы по тегам:

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