首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >转换为字符串会引发错误吗?

转换为字符串会引发错误吗?
EN

Stack Overflow用户
提问于 2016-08-16 12:23:54
回答 4查看 5.2K关注 0票数 30

我想知道转换为string,即str(sth)是否可以像float(sth)那样引发异常?我要求这样做是为了知道是否有必要将我的代码包装在:

代码语言:javascript
代码运行次数:0
运行
复制
try:
    x = str(value)
except ValueError:
    x = None

以确保执行不会因为转换失败而停止。

这在Python2和3中也有区别,因为str类在它们中是不同的吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-08-16 12:32:11

如果遇到一个在__str__中显式引发异常的自定义类(如果未定义__str__,则为__repr__ )。或者,例如,从bytes返回__str__对象的类

代码语言:javascript
代码运行次数:0
运行
复制
class Foo:
    def __str__(self):
        return b''

str(Foo()) # TypeError: __str__ returned non-string (type bytes)

但就我个人而言,我从来没有见过这样的事,我敢肯定没有人见过,这样做是愚蠢的。同样,在__str__或edge案例的实现中出现一个愚蠢的错误可能会创建另一个Exception。看看如何将Python推向这些边缘情况是很有趣的(请看这里的https://stackoverflow.com/a/38982099/4952130答案)。

除了这种情况之外,在这种情况下,通常不会产生异常,因为它是在Py2Py3中为所有它们定义的。

对于用户定义的类,如果没有在Python3中定义,str将默认使用object.__str__;在Python2中,如果类是一个新的样式类(从object继承),则使用它。

如果一个类是一个旧的样式类,我相信用于类的是classobj.__str__,实例是instance.__str__

一般来说,我不会理解这一点,特殊情况对此来说还不够特殊。

票数 28
EN

Stack Overflow用户

发布于 2016-08-16 12:31:53

理论上是可以的,但在实践中它几乎肯定不会。str函数的工作方式是它调用它正在转换为字符串的对象的__str__函数。内置于List、数值类型和其他类型中的类型将返回您期望的值,[x,y,z]表示List,数字作为字符串表示数字类型,等等。object有一个__str__方法,它提供像<generator object <genexpr> at 0x7fdb2fa6a640>这样的输出,这通常不是很有用,但不会引发异常。

因此,在任何内置程序上调用str几乎肯定不会引发异常(诚然,我在Python文档中找不到这方面的保证,但我无法想象会发生这种情况)。

也就是说,它是possible to override --自定义类的__str__方法。如果这样做了,那么这个方法就会引发一个异常,就像程序员可以编写的任何其他函数一样--一个有意的异常、一个不透明的IndexError等等。即使您没有覆盖__str__,如果您使用的是这样的模块,那么该模块的作者完全有可能在某种罕见的边缘犯了一些错误,这会引发异常。

的底线是:--如果每个人都做得对,就不应该这样做,但它可以。几乎在任何实际情况下,我都不会费心去尝试/抓住。

票数 19
EN

Stack Overflow用户

发布于 2016-08-16 18:32:04

很容易。您可以使用一个具有递归-不安全的__str____repr__的容器类来结束引用循环:

代码语言:javascript
代码运行次数:0
运行
复制
import numpy

x = numpy.empty([1], dtype=object)
x[0] = x
str(x)  # RuntimeError: maximum recursion depth exceeded

或者只是一个非常嵌套的对象:

代码语言:javascript
代码运行次数:0
运行
复制
x = []
for i in xrange(2000):
    x = [x]

str(x)  # RuntimeError: maximum recursion depth exceeded while getting the repr of a list

见鬼,即使只是内置类型,你也可以得到比例外更糟糕的东西:

代码语言:javascript
代码运行次数:0
运行
复制
x = {}
for i in range(1000000):
    x = {1: x}
str(x)  # python.exe has stopped working
        # Windows can check online for a solution to the problem.

这是一个C堆栈溢出,因为dict_repr (目前)不使用Py_EnterRecursiveCall。你不能用except块捕捉到这一点!

回到更常见的错误,您可以有一个死对象的weakref.proxy

代码语言:javascript
代码运行次数:0
运行
复制
import weakref

class Foo(object):
    pass

str(weakref.proxy(Foo()))  # ReferenceError: weakly-referenced object no longer exists

或者,只需编写一个类,在__str____repr__中引发您想要的任何内容。

代码语言:javascript
代码运行次数:0
运行
复制
class Foo(object):
    def __str__(self):
        raise Exception

str(Foo())  # Raises an Exception

特定于Python2,您可以得到这样一种情况,即print对对象进行处理会产生部分输出,然后引发异常,尽管表面上它不应该达到打印任何内容的阶段:

代码语言:javascript
代码运行次数:0
运行
复制
class Foo(object):
    def __repr__(self):
        raise Exception

print [Foo()]  # Prints a single opening bracket, then raises an Exception!

这是由于过时的tp_print C级挂钩。

UnicodeEncodeError str-ing是一个包含非ASCII字符的unicode对象时,您还可以得到一个特定于Python2的str,因为Python2str对象是字节字符串:

代码语言:javascript
代码运行次数:0
运行
复制
str(u'\u1000')  # Fails on Python 2 only
票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38974889

复制
相关文章

相似问题

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