2016-12-23 68 views
1

我有一个用例,我想清理作为输入给str类的字符串。换句话说,删除字符串中的控制字符。在子类字符串中的Santizing输入不能按预期工作

我想这

[[email protected] bin]$ ipython 
Python 2.7.12 (default, Sep 29 2016, 13:30:34) 
Type "copyright", "credits" or "license" for more information. 

IPython 3.2.1 -- An enhanced Interactive Python. 
?   -> Introduction and overview of IPython's features. 
%quickref -> Quick reference. 
help  -> Python's own help system. 
object? -> Details about 'object', use 'object??' for extra details. 

In [1]: class LogString(str): 
    ...:  def __init__(self, msg, *args, **kwargs): 
    ...:   nstr = msg.replace('\xc2', '') 
    ...:   nstr = nstr.replace('\xa0', ' ') 
    ...:   super(LogString, self).__init__(nstr, *args, **kwargs) 
    ...:   

In [2]: repr(LogString('Testing this out')) 
Out[2]: "'Testing\\xc2\\xa0this\\xc2\\xa0out'" 

我知道这个具体情况更换工作。

[[email protected] bin]$ ipython 
Python 2.7.12 (default, Sep 29 2016, 13:30:34) 
Type "copyright", "credits" or "license" for more information. 

IPython 3.2.1 -- An enhanced Interactive Python. 
?   -> Introduction and overview of IPython's features. 
%quickref -> Quick reference. 
help  -> Python's own help system. 
object? -> Details about 'object', use 'object??' for extra details. 

In [1]: i = 'Testing this out' 

In [2]: repr(i) 
Out[2]: "'Testing\\xc2\\xa0this\\xc2\\xa0out'" 

In [3]: i = i.replace('\xc2', '') 

In [4]: repr(i.replace('\xa0', ' ')) 
Out[4]: "'Testing this out'" 

In [5]: 

我不存储原始字符串,除了临时变量。在将它传递给树之前,我将替换角色。为什么创建的对象具有原始字符串而不是“已清理”字符串?

回答

1

Python中的字符串是不可变的。由于您的子类为str,因此一旦提供值就无法更改值。相反,重写__new__静态方法:

class LogString(str): 
    def __new__(cls, msg): 
     nstr = msg.replace('\xc2', '') 
     nstr = nstr.replace('\xa0', ' ') 
     return str.__new__(cls, nstr) 

希望这有助于!

+0

我测试了这一点,它的工作。我在__new__上找到的文件也证实了你的说法。我仍然不明白为什么我的例子不起作用。在__init__ msg之前执行__new__方法,从那时起msg是不可变的?这是什么原因来重载__new__方法,以便str的__new__方法不会运行?如果我写的是正确的,那么str的__new__方法是否可以做任何有用的工作,我可能想在我的方法中进行复制? – Mogget

+0

@Mogget没错,'__new__'方法甚至在创建对象之前执行,而'__init__'实际上是执行的实例的第一个函数。这就是为什么前者是静态方法的原因,在创建对象之前就要更改字符串。不知道你最后一个问题的含义是什么,你在最后一行中调用原始str的__new__方法! – cdonts