0

Considering this sample scenario:

#!/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')

Code works, tests passes. I'm just wondering if I can avoid calling custom_str.__new__() twice.

If I change custom_type.__new__() to return custom_str.new(value) it works, but them it'll be of type custom_str instead of custom_type.

On other hand, if I change it to return super(custom_type, cls).new(value) it gets into infinite recursion.

4

1 回答 1

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并拉入其自己的函数以解开依赖关系图。

于 2013-09-05T22:47:30.927 回答