Вы можете выполнить rtrim()
в строке в начале каждой итерации цикла.
function getProductCount($path)
{
$count = 0;
foreach (file($path) as $raw_name) {
$name = rtrim($raw_name);
if($name == "")
{
$count = $count + 1;
}
}
return $count;
}
Нет, нет. Вы не можете объявить переменную или значение как константу в 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
PEP 591 имеет 'заключительный' спецификатор. Осуществление до средства проверки типа.
, Таким образом, можно сделать:
MY_CONSTANT: Final = 12407
В 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
Пифонический способ объявления «констант» - это, по сути, переменная уровня модуля:
RED = 1
GREEN = 2
BLUE = 3
А затем напишите свои классы или функции. Поскольку константы почти всегда являются целыми числами, и они также неизменны в Python, у вас очень мало шансов изменить их.
Если, конечно, вы явно не установили RED = 2
.
Нет ключевого слова 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
Пояснение кода:
константу
, которая принимает выражение и использует его для создания «получателя» - функции, которая только возвращает значение выражения.
в качестве украшения, чтобы быстро определить свойства, доступные только для чтения. И другим, более старомодным способом:
(Код довольно сложен, подробности ниже)
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, кажется, устарел.
property
для создания объекта, который можно «установить» или «получить». свойства
называются fset
и fget
.
function Здесь это - набор идиом, которые я создал как попытка улучшить некоторые уже доступные ответы.
я знаю, что использование константы не является pythonic, и Вы не должны делать этого дома!
Однако Python является таким динамическим языком! Этот форум показывает, как это возможно создание конструкций это стили как константы. Этот ответ имеет как основная цель для исследования то, что может быть выражено языком.
не будьте слишком резки со мной :-).
для получения дополнительной информации я записал блог сопровождения об этих идиомах .
В этом сообщении, я назову постоянную переменную к постоянной ссылке на значения (неизменной или иначе). Кроме того, я говорю, что переменная имеет замороженное значение, когда она ссылается на изменяемый объект, что клиентский код не может обновить свое значение (значения).
Эта идиома создает то, что похоже на пространство имен постоянных переменных (иначе 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"
Эта следующая идиома является модификацией , 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. Это - комбинация удивительно ответа простого 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 .
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'"