我想知道转换为string,即str(sth)
是否可以像float(sth)
那样引发异常?我要求这样做是为了知道是否有必要将我的代码包装在:
try:
x = str(value)
except ValueError:
x = None
以确保执行不会因为转换失败而停止。
这在Python2和3中也有区别,因为str
类在它们中是不同的吗?
发布于 2016-08-16 12:32:11
如果遇到一个在__str__
中显式引发异常的自定义类(如果未定义__str__
,则为__repr__
)。或者,例如,从bytes
返回__str__
对象的类
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答案)。
除了这种情况之外,在这种情况下,通常不会产生异常,因为它是在Py2
和Py3
中为所有它们定义的。
对于用户定义的类,如果没有在Python3中定义,str
将默认使用object.__str__
;在Python2中,如果类是一个新的样式类(从object
继承),则使用它。
如果一个类是一个旧的样式类,我相信用于类的是classobj.__str__
,实例是instance.__str__
。
一般来说,我不会理解这一点,特殊情况对此来说还不够特殊。
发布于 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__
,如果您使用的是这样的模块,那么该模块的作者完全有可能在某种罕见的边缘犯了一些错误,这会引发异常。
的底线是:--如果每个人都做得对,就不应该这样做,但它可以。几乎在任何实际情况下,我都不会费心去尝试/抓住。
发布于 2016-08-16 18:32:04
很容易。您可以使用一个具有递归-不安全的__str__
或__repr__
的容器类来结束引用循环:
import numpy
x = numpy.empty([1], dtype=object)
x[0] = x
str(x) # RuntimeError: maximum recursion depth exceeded
或者只是一个非常嵌套的对象:
x = []
for i in xrange(2000):
x = [x]
str(x) # RuntimeError: maximum recursion depth exceeded while getting the repr of a list
见鬼,即使只是内置类型,你也可以得到比例外更糟糕的东西:
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
:
import weakref
class Foo(object):
pass
str(weakref.proxy(Foo())) # ReferenceError: weakly-referenced object no longer exists
或者,只需编写一个类,在__str__
或__repr__
中引发您想要的任何内容。
class Foo(object):
def __str__(self):
raise Exception
str(Foo()) # Raises an Exception
特定于Python2,您可以得到这样一种情况,即print
对对象进行处理会产生部分输出,然后引发异常,尽管表面上它不应该达到打印任何内容的阶段:
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
对象是字节字符串:
str(u'\u1000') # Fails on Python 2 only
https://stackoverflow.com/questions/38974889
复制相似问题