在此示例中,使用元类提供了一个不错的解决方案。元类的用途有限,但效果很好。
>>> class metaInit(type): def __call__(cls, *args, **kwargs): if args or kwargs: return super().__call__(*args, **kwargs) return cls.__new__(cls)>>> class String(metaclass=metaInit): def __init__(self, string): self.__string = tuple(string.split()) self.__simple = tuple(self.__simple()) def __simple(self): letter = lambda s: ''.join(filter(lambda s: 'a' <= s <= 'z', s)) return filter(bool, map(letter, map(str.lower, self.__string))) def __eq__(self, other): assert isinstance(other, String) return self.__simple == other.__simple def __getitem__(self, key): assert isinstance(key, slice) string = String() string.__string = self.__string[key] string.__simple = self.__simple[key] return string def __iter__(self): return iter(self.__string)>>> String('Hello, world!')[1:]<__main__.String object at 0x02E78830>>>> _._String__string, _._String__simple(('world!',), ('world',))>>>附录:
六年后,我的观点比我自己的方法更支持AlexMartelli的答案。在仍然考虑元类的情况下,以下答案显示了如何使用和不使用它们都可以解决问题:
#! /usr/bin/env python3METHOD = 'metaclass'class NoInitmeta(type): def new(cls): return cls.__new__(cls)class String(metaclass=NoInitmeta if METHOD == 'metaclass' else type): def __init__(self, value): self.__value = tuple(value.split()) self.__alpha = tuple(filter(None, ( ''.join(c for c in word.casefold() if 'a' <= c <= 'z') for word in self.__value))) def __str__(self): return ' '.join(self.__value) def __eq__(self, other): if not isinstance(other, type(self)): return NotImplemented return self.__alpha == other.__alpha if METHOD == 'metaclass': def __getitem__(self, key): if not isinstance(key, slice): raise NotImplementedError instance = type(self).new() instance.__value = self.__value[key] instance.__alpha = self.__alpha[key] return instance elif METHOD == 'classmethod': def __getitem__(self, key): if not isinstance(key, slice): raise NotImplementedError instance = self.new() instance.__value = self.__value[key] instance.__alpha = self.__alpha[key] return instance @classmethod def new(cls): return cls.__new__(cls) elif METHOD == 'inline': def __getitem__(self, key): if not isinstance(key, slice): raise NotImplementedError cls = type(self) instance = cls.__new__(cls) instance.__value = self.__value[key] instance.__alpha = self.__alpha[key] return instance else: raise ValueError('METHOD did not have an appropriate value') def __iter__(self): return iter(self.__value)def main(): x = String('Hello, world!') y = x[1:] print(y)if __name__ == '__main__': main()


