首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Unicode的子类移植到Python 3

将Unicode的子类移植到Python 3
EN

Stack Overflow用户
提问于 2018-02-28 21:06:07
回答 1查看 123关注 0票数 0

我正在将遗留代码库从Python2.7移植到Python3.6。在这个代码库中,我有一些例子,比如:

代码语言:javascript
复制
class EntityName(unicode):

    @staticmethod
    def __new__(cls, s):
        clean = cls.strip_junk(s)
        return super(EntityName, cls).__new__(cls, clean)

    def __init__(self, s):
        self._clean = s
        self._normalized = normalized_name(self._clean)
        self._simplified = simplified_name(self._clean)
        self._is_all_caps = None
        self._is_all_lower = None
        super(EntityName, self).__init__(self._clean)

它可以这样叫:

代码语言:javascript
复制
EntityName("Guy DeFalt")

当将它移植到Python3时,上面的代码会失败,因为unicode不再是您可以扩展的类(至少,如果有一个类似的类,我就找不到它)。考虑到str现在是unicode,我尝试只交换str,但是父init不接受我试图传递的字符串值:

代码语言:javascript
复制
TypeError: object.__init__() takes no parameters

这是有意义的,因为str没有__init__方法--这似乎不是使用该类的惯用方法。因此,我的问题有两个主要分支:

  • 是否有更好的方法来移植那些对旧unicode类进行子类分类的类?
  • 如果子类str是适当的,我应该如何修改__init__函数的惯用行为?
EN

回答 1

Stack Overflow用户

发布于 2019-03-28 12:51:24

在Python 3中子类字符串或其他不可变类的正确方法与Python 2中相同:

代码语言:javascript
复制
class MyString(str):
  def __new__(cls, initial_arguments): # no staticmethod
     desired_string_value = get_desired_string_value(initial_arguments)
     return super(MyString, cls).__new__(cls, desired_string_value)
     # can be shortened to super().__new__(...)
  def __init__(self, initial_arguments): # arguments are unused
     self.whatever = whatever(self)
     # no need to call super().__init__(), but if you must, do not pass arguments 

你的样本有几个问题。首先,为什么__new__@staticmethod?它是@classmethod,尽管您不需要指定它。第二,代码似乎是在这样的假设下运行的:当您调用超类的__new__时,它也以某种方式调用了您的__init__。我是从self._clean应该如何设置的角度得出这个结论的。事实并非如此。当您调用MyString(arguments)时,会发生以下情况:

  • 首先,Python使用类参数(通常称为__new__ )和arguments调用arguments__new__必须返回类实例。要做到这一点,它可以创建它,就像我们所做的那样,或者做一些其他的事情;例如,它可能返回一个现有的,或者事实上,任何东西。
  • 然后,Python使用从__init__接收到的实例(这个参数通常称为self)和相同的arguments调用arguments
  • (有一种特殊情况:如果__init__返回不是传递类的子类,__new__就不会调用__new__。)

Python使用类层次结构来查看要调用哪个__new____init__。在这两个方法中,需要正确地排序参数并使用适当的超类调用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49038559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档