1119 Не обязательно легко, но возможно. Нам нужно создать новый тип и использования : Попытка переназначения члена по-прежнему приводит к более дружественной ошибке: Чтобы немного переназначить класс, мы можем написать декоратор для инкапсуляции процесса. : и используется: Обратите внимание, что все еще можно перезаписать обычные атрибуты, такие как функции: и используемые : Даже это может быть заблокировано, но я оставлю это (пока) в качестве упражнения для кого-то еще. 1 sup> Это только второй случай, который я видел, когда требуется подкласс Раскрытие: я являюсь автором Python stdlib EnumMeta
1 sup>, создать Enum
обычным образом, а затем переназначить тип после создания Enum
: from enum import Enum, EnumMeta
class FrozenEnum(EnumMeta):
"prevent creation of new attributes"
def __getattr__(self, name):
if name not in self._member_map_:
raise AttributeError('%s %r has no attribute %r'
% (self.__class__.__name__, self.__name__, name))
return super().__getattr__(name)
def __setattr__(self, name, value):
if name in self.__dict__ or name in self._member_map_:
return super().__setattr__(name, value)
raise AttributeError('%s %r has no attribute %r'
% (self.__class__.__name__, self.__name__, name))
class Color(Enum):
red = 1
green = 2
blue = 3
Color.__class__ = FrozenEnum
>>> type(Color)
>>> Color.blue = 9
Traceback (most recent call last):
...
AttributeError: Cannot reassign members.
def freeze(enum_class):
enum_class.__class__ = FrozenEnum
return enum_class
@freeze
class Color(Enum):
red = 1
green = 2
blue = 3
@freeze
class Color(Enum):
red = 1
green = 2
blue = 3
def huh(self):
print("Huh, I am %s!" % self.name)
>>> Color.huh
EnumMeta
. О других см. this question
. Enum
, enum34
backport и Advanced Enumeration (aenum
) библиотека. I>
Единственными проблемами, о которых я могу думать, является gettype () и is_array () функции. Проверьте свой код на
gettype($FakeArray) == 'array'
is_array($FakeArray)
Поскольку, хотя можно использовать объект точно так же, как массив, он будет все еще идентифицирован как объект.
Другие различия включают '+' оператор для массивов (слияние) и отказ всего array_*
функции, включая наиболее часто используемое array_merge
и array_shift
.
В дополнение к точкам, сделанным выше, Вы не смогли бы сделать работу подсказок типа массива пространства пользователя с экземплярами Вашего класса. Например:
<?php
function f(array $a) { /*...*/ }
$ao = new ArrayObject();
f($ao); //error
?>
Вывод:
Catchable fatal error: Argument 1 passed to f() must be an array, object given