如何从仅影响一个 class 的内置函数中导入对象?
How to import object from builtins affecting just one class?
我正在使用 future
将 newstyle
class 的代码从 python2 转换为 python3。我的项目在 Django 1.11
我在 forms.py 中有一个 class 作为:
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
测试通过。
但是当我添加了未来检查时,我得到了未来差异错误,因此每个 class 都必须转换为新样式。我希望它在 Python2 和 Python3 中都能工作。
这个模块 builtins
模块导入是否可以只影响一个 class 而不会影响 forms.py
文件中的其他模块。或者有其他方法可以解决这个问题吗?
这是python2方式。
class Address(object):
在python3类中隐式继承对象,所以应该是这样的;
class Address:
您 运行 遇到的问题似乎来自两个不同的 Python 2 现代化工具。您似乎正在使用 django.utils.six
中的 python_2_unicode_compatible
装饰器
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__
方法方面略有不同,因此它们会无限地相互调用,从而导致递归错误。
提供builtins.object的模块提供了自己的python_2_unicode_compatible
装饰器。您是否尝试过使用 django.utils.six
中的那个?
运行 今天进入这个,Patrick Haugh 主要描述了这个问题,除了 six 和 python_2_unicode_compatible
在 django 1.11 中没有被引用,问题中的版本和那个我在用。在我们的例子中,问题是 django 模型继承自 mixin,而 mixin 继承自 future.builtins.newobject
.
- newobject (from builtins import object) 添加一个名为
unicode: https://github.com/PythonCharmers/python-future/blob/master/src/future/types/newobject.py#L41
- django admin 有一个日志功能创建一个 LogEntry 包含
对象的文本表示。 https://github.com/django/django/blob/stable/1.11.x/django/contrib/admin/options.py#L741
- 使用的文本表示法是
object.__unicode__
:https://github.com/django/django/blob/stable/1.11.x/django/utils/encoding.py#L77
__unicode__
是对 __str__
的封装,在未来的 package 中
__str__
for django db models 在 django https://github.com/django/django/blob/stable/1.11.x/django/db/models/base.py#L595 中实现为围绕 unicode 的包装器
我们没有很好的解决方案,除了如果我们需要访问两者,将 future 显式导入 from builtins import object as future_object
,并通过 运行 futurize --stage2 -x object
而不是禁用整个修复futurize --stage2
我正在使用 future
将 newstyle
class 的代码从 python2 转换为 python3。我的项目在 Django 1.11
我在 forms.py 中有一个 class 作为:
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
测试通过。
但是当我添加了未来检查时,我得到了未来差异错误,因此每个 class 都必须转换为新样式。我希望它在 Python2 和 Python3 中都能工作。
这个模块 builtins
模块导入是否可以只影响一个 class 而不会影响 forms.py
文件中的其他模块。或者有其他方法可以解决这个问题吗?
这是python2方式。
class Address(object):
在python3类中隐式继承对象,所以应该是这样的;
class Address:
您 运行 遇到的问题似乎来自两个不同的 Python 2 现代化工具。您似乎正在使用 django.utils.six
python_2_unicode_compatible
装饰器
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__
方法方面略有不同,因此它们会无限地相互调用,从而导致递归错误。
提供builtins.object的模块提供了自己的python_2_unicode_compatible
装饰器。您是否尝试过使用 django.utils.six
中的那个?
运行 今天进入这个,Patrick Haugh 主要描述了这个问题,除了 six 和 python_2_unicode_compatible
在 django 1.11 中没有被引用,问题中的版本和那个我在用。在我们的例子中,问题是 django 模型继承自 mixin,而 mixin 继承自 future.builtins.newobject
.
- newobject (from builtins import object) 添加一个名为 unicode: https://github.com/PythonCharmers/python-future/blob/master/src/future/types/newobject.py#L41
- django admin 有一个日志功能创建一个 LogEntry 包含 对象的文本表示。 https://github.com/django/django/blob/stable/1.11.x/django/contrib/admin/options.py#L741
- 使用的文本表示法是
object.__unicode__
:https://github.com/django/django/blob/stable/1.11.x/django/utils/encoding.py#L77 __unicode__
是对__str__
的封装,在未来的 package 中
__str__
for django db models 在 django https://github.com/django/django/blob/stable/1.11.x/django/db/models/base.py#L595 中实现为围绕 unicode 的包装器
我们没有很好的解决方案,除了如果我们需要访问两者,将 future 显式导入 from builtins import object as future_object
,并通过 运行 futurize --stage2 -x object
而不是禁用整个修复futurize --stage2