可以在Python中创建自定义字符串文字前缀?

时间:2016-05-13 07:17:18

标签: python string prefix string-literals

假设我有一个派生自str的自定义类,它实现/覆盖了一些方法:

class mystr(str):
    # just an example for a custom method:
    def something(self):
        return "anything"

现在我必须通过在构造函数中传递一个字符串来手动创建mystr的实例:

ms1 = mystr("my string")

s = "another string"
ms2 = mystr(s)

这不是太糟糕,但它导致使用类似于b'bytes string'r'raw string'u'unicode string'的自定义字符串前缀会很酷。

在Python中以某种方式可以创建/注册像m这样的自定义字符串文字前缀,以便文字m'my string'生成mystr的新实例吗? 或者这些前缀是否已经硬编码到Python解释器中?

3 个答案:

答案 0 :(得分:13)

这些前缀在解释器中是硬编码的,你不能注册更多的前缀。

可以做什么,是使用自定义源编解码器对Python文件进行预处理。这是一个相当简洁的黑客,需要您注册自定义编解码器,并理解和应用源代码转换。

Python允许您在顶部使用特殊注释指定源代码的编码:

# coding: utf-8

会告诉Python使用UTF-8编码的源代码,并在解析之前相应地解码文件。 Python在codecs模块注册表中查找编解码器。 您可以注册自己的编解码器

pyxl project使用这个技巧从Python文件中解析HTML语法,用实际的Python语法替换它们来构建HTML,所有这些都在“解码”步骤中完成。请参阅该项目中的codec package,其中register module注册了custom codec search function,在Python实际解析和编译之前,它会转换源代码。在site-packages目录中安装了custom .pth file,以便在Python启动时加载此注册步骤。另一个用于解析Ruby样式字符串格式的项目是interpy

然后你需要做的就是构建一个这样的编解码器,它将解析一个Python源文件(用它标记它,可能用tokenize module)并用你的自定义前缀替换字符串文字{{1}调用。您要解析的任何文件都标有mystr(<string literal>)

我会将这部分作为练习留给读者。祝你好运!

注意,然后将此转换的结果编译为字节码,该字节码被缓存;您的转换只需要为每个源代码修订版运行一次,使用您的编解码器的所有其他模块导入都将加载缓存的字节码。

答案 1 :(得分:2)

可以使用运算符重载将str隐式转换为自定义类

class MyString(str):
    def __or__( self, a ):
        return MyString(self + a)

m = MyString('')
print( m, type(m) )
#('', <class 'MyString'>)
print m|'a', type(m|'a')
#('a', <class 'MyString'>)

这避免了使用括号有效地模拟带有一个额外字符的字符串前缀-我选择将其作为|,但也可以是&或其他二进制比较运算符。

答案 2 :(得分:1)

尽管上述解决方法很不错,但它们可能很危险。黑客Python确实不是一个好主意。虽然否则您实际上无法做一个前缀, 您可以执行以下操作:

class MyString(str):
    def something(self):
        return MyString("anything")

m = MyString

# The you can do:
m("hi")
# Rather than:
# m"hi"

这可能是您可以找到的最佳安全解决方案。 输入两个括号实际上并不是那么多,并且可以减少代码阅读者的困惑。