代码之家  ›  专栏  ›  技术社区  ›  Deesha

从只影响一个类的内置项导入对象

  •  6
  • Deesha  · 技术社区  · 6 年前

    我正在将代码从python2转换为python3 newstyle 类使用 future . 我的项目是django1.11

    我有一节英语课表单.py作为:

    class Address:
        ...rest of code...
    
    class AddressForm(Address, forms.ModelForm):
        ...rest of code...
    

    在Python 2中

    转换为:

    from buitlins import object
    class Address(object):
            ...rest of code...
    
    class AddressForm(Address, forms.ModelForm):
        ...rest of code...
    

    在Python 3中

    我有一个selenium测试,在将此窗体转换为Python3后调用它时失败,错误如下:

    File "<path_to_venv>/local/lib/python2.7/site-packages/django/utils/six.py", line 842, in <lambda>
    klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
    File "<path_to_venv>/local/lib/python2.7/site-packages/future/types/newobject.py", line 78, in __unicode__
    s = type(self).__str__(self)
    RuntimeError: maximum recursion depth exceeded
    

    但是,当我删除导入 from buitlins import object 测试通过了。

    builtins 模块导入只能影响一个类,而不会影响系统中的其他类 forms.py 文件。或者有其他方法来处理这个问题吗?

    2 回复  |  直到 4 年前
        1
  •  6
  •   Patrick Haugh    6 年前

    您遇到的问题似乎来自两个不同的python2现代化工具。你好像在用 python_2_unicode_compatible django.utils.six

    def python_2_unicode_compatible(klass):
        """
        A decorator that defines __unicode__ and __str__ methods under Python 2.
        Under Python 3 it does nothing.
        To support Python 2 and 3 with a single code base, define a __str__ method
        returning text and apply this decorator to the class.
        """
        if PY2:
            if '__str__' not in klass.__dict__:
                raise ValueError("@python_2_unicode_compatible cannot be applied "
                                 "to %s because it doesn't define __str__()." %
                                 klass.__name__)
            klass.__unicode__ = klass.__str__
            klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
        return klass
    

    继承自 newobject __unicode__ 方法

    def __unicode__(self):
        # All subclasses of the builtin object should have __str__ defined.
        # Note that old-style classes do not have __str__ defined.
        if hasattr(self, '__str__'):
            s = type(self).__str__(self)
        else:
            s = str(self)
        if isinstance(s, unicode):
            return s
        else:
            return s.decode('utf-8')
    

    因为两者在提供两者的策略上略有不同 __unicode码__ __str__ 方法,它们会无限地互相调用,这会导致递归错误。

    提供内置对象提供自己的 python_2_unicode_compatible 装饰工。你有没有试过用它来代替 django.utils.six公司 ?

        2
  •  0
  •   ruohola    6 年前

    class Address(object):
    

    在python3中,类隐式继承对象,所以应该是这样的;

    class Address:
    
        3
  •  0
  •   Mark    4 年前

    今天遇到了这个,帕特里克·霍主要描述了这个问题,除了那个 six python_2_unicode_compatible 在Django1.11中没有引用,这个问题中的版本和我正在使用的版本。在我们的例子中,问题是django模型是从mixin继承的,mixin是从 future.builtins.newobject .

    1. newobject(来自builtins import object)添加一个名为 unicode码 https://github.com/PythonCharmers/python-future/blob/master/src/future/types/newobject.py#L41
    2. django admin有一个日志记录功能,它创建一个包含 对象的文本表示。 https://github.com/django/django/blob/stable/1.11.x/django/contrib/admin/options.py#L741
    3. 使用的文本表示法是 object.__unicode__ : https://github.com/django/django/blob/stable/1.11.x/django/utils/encoding.py#L77
    4. __unicode__ 周围有一个包装纸吗 __str__ 在未来的一揽子计划中
    5. 对于django,db模型是作为包装器实现的 unicode码 https://github.com/django/django/blob/stable/1.11.x/django/db/models/base.py#L595

    我们没有一个很好的解决方案,除了明确地将未来作为 from builtins import object as future_object 如果我们需要访问这两者,并通过运行 futurize --stage2 -x object 而不是 futurize --stage2