自定义子类化问题

时间:2013-09-05 22:44:00

标签: python

考虑此示例场景:

#!/usr/bin/python
import binascii
import cProfile
import re

class custom_str(str):
    __strip_non_hex = re.compile(r'^[^:]+:|[^0-9A-Fa-f]')

    def __new__(cls, value):
        return super(custom_str, cls).__new__(cls, value)

    @classmethod
    def new(cls, value):
        # creates a pure-hexadecimal string
        return cls(re.sub(cls.__strip_non_hex, '', value))

class custom_type(custom_str):
    def __new__(cls, value):
        # here I've to use custom_str.new()
        return super(custom_type, cls).__new__(cls, custom_str.new(value))

    @classmethod
    def new(cls, value):
        return cls('hex:%s' % (binascii.hexlify(value)))

if __name__ == '__main__':
    # tests
    v = custom_str('666f6f')
    assert v == '666f6f'
    assert type(v) == custom_str
    v = custom_str.new('66,6f,6f')
    assert v == '666f6f'
    assert type(v) == custom_str
    v = custom_type('hex:66,6f,6f')
    assert v == '666f6f'
    assert type(v) == custom_type
    v = custom_type.new('foo')
    assert v == '666f6f'
    assert type(v) == custom_type
    # profiling
    cProfile.run("custom_type.new('foo')", sort='call')

代码有效,测试通过。我只是想知道我是否可以避免两次致电custom_str.__new__()

如果我将custom_type.__new__()更改为return custom_str.new(value)它可以正常运行,但它们的类型为custom_str而不是custom_type

另一方面,如果我将其更改为return super(custom_type, cls).new(value),它将进入无限递归。

1 个答案:

答案 0 :(得分:1)

_strip_non_hex = re.compile(r'^[^:]+:|[^0-9A-Fa-f]')

def _strip(string):
    return re.sub(_strip_non_hex, '', value)

class custom_str(str):
    @classmethod
    def new(cls, value):
        # creates a pure-hexadecimal string
        return custom_str.__new__(cls, _strip(value))

class custom_type(custom_str):
    def __new__(cls, value):
        return super(custom_type, cls).__new__(cls, _strip(value))

    @classmethod
    def new(cls, value):
        return cls('hex:%s' % (binascii.hexlify(value)))

将非十六进制剥离逻辑从new中拉出并放入其自己的函数中以解开依赖图。