1

我设计了一个代理类,它允许我用工厂方法替换任何类型/类,并且仍然保留类对象的大部分功能。这是它如何工作的示例:

class ProxyClass:
    def __init__(self, cls):
        self._ProxyClass_cls = cls
    def __getattr__(self, name):
        return getattr(self._ProxyClass_cls, name)

class _strProxy(ProxyClass):
    def __call__(self, s):
        if '\n' in s:
            raise ValueError
        if s not in self._cache:
            self._cache[s] = self._ProxyClass_cls(s)
        return self._cache[s]

str = _strProxy(str)
str._cache = {}


>>> s = str('hello')
>>> s
'hello'
>>> type(s)
<type 'str'>
>>> str('hello\n')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __call__
ValueError

我喜欢这种工厂方法的实现,因为它完全替换了原始类对象,并且仍然允许以下内容:

>>> map(str.split, [str('foo bar'), str('bar foo')])
[['foo', 'bar'], ['bar', 'foo']]

我发现的唯一问题是对类本身的操作,例如repr()

>>> repr(str)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor '__repr__' of 'str' object needs an argument

在此示例中,repr()正在尝试调用str.__repr__()而不是type.__repr__(str). 我尝试修复更改str.__class__,但发现在这种情况下这是不可能的:

>>> str.__class__ = type
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __class__ must be set to a class

有谁知道恢复功能的任何方法repr(str)或另一种方法来完成我正在做的事情?

4

2 回答 2

0

为什么不做

>>> class _strPproxy(ProxyClass):
...     def __call__(self, s):
...         self.s = s
...         if '\n' in s:
...             raise ValueError
...         if s not in self._cache:
...             self._cache[s] = self._ProxyClass_cls(s)
...         return self._cache[s]
...     def __repr__(self): 
...         return repr(self.s)
于 2012-05-24T21:35:04.950 回答
0

确保您的所有类都继承自object

class ProxyClass(object):

在 Python 3.x 中,所有类都继承自object反正,所以你不需要这样做。但是在 Python 2.x 中,除非所有涉及的类都是从object.

repr(str)进行上述更改后,对我来说效果很好。

于 2012-05-24T21:35:11.983 回答