python - 在 python 中从 str 或 unicode 继承时是否有可能在分配后保留类实例?

标签 python string inheritance unicode

我想答案是否定的,但如果有机会的话,我的生活会轻松很多。考虑以下代码:

class SchemaString(unicode):
    _schema = dict()

    def validate(self):
        errors = []
        # some validation function using class propertie _schema, not important
        return sorted(list(set(errors)))

s = SchemaString("Hello")
e0 = s.validate()

我希望以下内容仍然有效:

s = "World"
e1 = s.validate()
>> AttributeError: 'str' object has no attribute 'validate'

因此我的问题是,在新的赋值之后是否有可能仍然使用相同的对象,这样我仍然可以使用“验证”方法。换句话说,在python中使用'='时是否使用了一些内部赋值函数,这个赋值函数可以被覆盖吗?

最佳答案

您不能覆盖“顶级”分配。但是,如果您可以拥有一个根对象并在命名空间对象中使用变量,那么是的,您只需为该对象编写 __setattr__ 方法。它可以是一个相当简单的类,你可以创建一个只有一个字母的实例,所以它不会对阅读你的代码造成负面干扰——相反,很容易察觉到一些特别的事情正在发生:

class NS(object):
    def __setattr__(self, name, value):
        if name not in self.__dict__:
            # Normal, first time assignment:
            super(NS, self).__setattr__(name, value)
            return
        cls = type(self.__dict__[name])
        instance = cls(value)
        super(NS, self).__setattr__(name, instance)

n = NS()

在非交互式提示上:

In [110]: class MyString(str): pass
     ...: 
     ...: n.s = MyString()
     ...: 
     ...: n.s = "bla"
     ...: type(n.s)
     ...: 
Out[110]: __main__.MyString

不求助于容器对象,不,没有办法覆盖赋值 - 底层生成的代码是完全不同的 - 因为字节码直接在“全局”字典中设置变量当前帧,或者如果代码在函数内部运行,则在快速变量缓存中 - 这意味着甚至不会触及 locals 字典。也就是说,可以考虑一个观察者模式来处理全局字典的变化,并在模块中更改全局变量时采取行动(例如,如果您的应用程序在自定义事件循环中运行) - 但这太老套了,而且无论如何都不适用于全局变量。命名空间对象简单了几个数量级。

就是说,如果您使用的是 Python3,(您应该 - 然后一方面 - 不要担心文本的“unicode”或“str”) - 您也可以覆盖赋值类主体中的运算符:为此,您必须使用 __prepare__ 方法创建一个自定义元类,该方法将创建一个映射对象,您想要的逻辑将在其中__setitem__ 方法。在这种情况下,Python 代码在找到赋值语句时只调用这个类似字典的对象的 __setitem__ 方法。

关于python - 在 python 中从 str 或 unicode 继承时是否有可能在分配后保留类实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44460073/

相关文章:

c - C 中的字符串排序

c - 通过用户输入操作 C 中的字符串

java - 能解释一下输出是怎么来的吗?

javascript - Django View 中的日期时间在 Javascript 中使用

python - 将日期插入 Python MySQLdb

python - 具有非同质任务的 Celery

python - 使用 sort_index() 时的关键函数

c - 为什么 C 函数 strlen() 返回错误的 char 长度?

c++ - 将 'typedef' 从基类传播到 'template' 的派生类

c++ - 继承类模板有好处吗?