Python 中使用内置 str() 类型的潜在异常
Potential Exceptions using builtin str() type in Python
在 Python 中使用 int
和 float
等内置类型时,通常在输入可能不可靠的情况下使用异常处理:
def friendly_int_convert(val):
"Convert value to int or return 37 & print an alert if conversion fails"
try:
return int(val)
except ValueError:
print('Sorry, that value doesn\'t work... I chose 37 for you!')
return 37
使用 str()
时是否需要注意任何突出的边缘情况?
def friendly_str_convert(val):
"Convert value to str or return 'yo!' & print an alert if conversion fails"
try:
return str(val)
except Exception: # Some specific Exception here
print('Sorry, that value doesn\'t work... I chose \'yo!\' for you!')
return 'yo!'
我真的不喜欢使用宽泛的 Exception
,因为像 NameError
这样的情况表示代码有问题,应该会引发错误。我考虑过 UnicodeError
作为候选人,但我不确定 str()
是否会导致它(相对于 foo.encode()
和 foo.decode()
更容易理解)并且会喜欢什么输入的例子,如果有的话,会触发它。
总结:即使输入不可靠,在没有 try
/ except
块的情况下使用 str()
通常是否安全?
str
和 int
在这方面有很大的不同。 int
绝对可以提高 TypeError
和 ValueError
.
据我所知,str
可以为普通对象引发的唯一例外是 UnicodeEncodeError
:
>>> s = u"a\xac\u1234\u20ac\U00008000"
>>> str(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-4: ordinal not in range(128)
这只会发生在 python2.x。
当然,我可以很容易地使 class 失败,几乎可以想象到任何异常:
>>> class MyError(Exception):
... pass
...
>>> class Foo(object):
... def __str__(self):
... raise MyError
...
>>> f = Foo()
>>> str(f)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __str__
__main__.MyError
在大多数情况下,我会质疑一些隐含的假设,即所有异常 都需要 在此时处理。一般来说,最好只处理您知道如何处理的异常。在这种情况下,由于用户将垃圾放入函数而发生的奇异异常可能应该在垃圾进入的级别处理——而不是在函数本身内。捕获错误并返回一些可能无意义的值对调试问题等不会有太大帮助。
In summary: Is it generally safe to use str()
without a try
/ except
block even with unreliable input?
这取决于我们谈论的是哪种输入。您已将此问题标记为 Python 3,因此您无需担心使用 Python 2 和 Unicode 输入会遇到的 UnicodeEncodeErrors,但您收到的对象可以做很多事情__str__
或 __repr__
中的任何内容,几乎都会引发任何类型的异常。例如,
In [18]: import weakref
In [19]: class Foo(object): pass
In [20]: str(weakref.proxy(Foo()))
---------------------------------------------------------------------------
ReferenceError Traceback (most recent call last)
<ipython-input-20-396b2ab40052> in <module>()
----> 1 str(weakref.proxy(Foo()))
ReferenceError: weakly-referenced object no longer exists
考虑到您提出的问题,我愿意 except Exception as e:
。 Exception
是 Python 3 中的通用 "catch-all",用于 "normal" 异常(除了 "system-level" 由进程获取信号、KeyboardInterrupt
等引起的异常)。
如果我是你,我至少会记录实际的异常(e
在我上面的例子中),看看实际发生了什么(你的代码通过 except Exception:
).
在 Python 中使用 int
和 float
等内置类型时,通常在输入可能不可靠的情况下使用异常处理:
def friendly_int_convert(val):
"Convert value to int or return 37 & print an alert if conversion fails"
try:
return int(val)
except ValueError:
print('Sorry, that value doesn\'t work... I chose 37 for you!')
return 37
使用 str()
时是否需要注意任何突出的边缘情况?
def friendly_str_convert(val):
"Convert value to str or return 'yo!' & print an alert if conversion fails"
try:
return str(val)
except Exception: # Some specific Exception here
print('Sorry, that value doesn\'t work... I chose \'yo!\' for you!')
return 'yo!'
我真的不喜欢使用宽泛的 Exception
,因为像 NameError
这样的情况表示代码有问题,应该会引发错误。我考虑过 UnicodeError
作为候选人,但我不确定 str()
是否会导致它(相对于 foo.encode()
和 foo.decode()
更容易理解)并且会喜欢什么输入的例子,如果有的话,会触发它。
总结:即使输入不可靠,在没有 try
/ except
块的情况下使用 str()
通常是否安全?
str
和 int
在这方面有很大的不同。 int
绝对可以提高 TypeError
和 ValueError
.
据我所知,str
可以为普通对象引发的唯一例外是 UnicodeEncodeError
:
>>> s = u"a\xac\u1234\u20ac\U00008000"
>>> str(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-4: ordinal not in range(128)
这只会发生在 python2.x。
当然,我可以很容易地使 class 失败,几乎可以想象到任何异常:
>>> class MyError(Exception):
... pass
...
>>> class Foo(object):
... def __str__(self):
... raise MyError
...
>>> f = Foo()
>>> str(f)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __str__
__main__.MyError
在大多数情况下,我会质疑一些隐含的假设,即所有异常 都需要 在此时处理。一般来说,最好只处理您知道如何处理的异常。在这种情况下,由于用户将垃圾放入函数而发生的奇异异常可能应该在垃圾进入的级别处理——而不是在函数本身内。捕获错误并返回一些可能无意义的值对调试问题等不会有太大帮助。
In summary: Is it generally safe to use
str()
without atry
/except
block even with unreliable input?
这取决于我们谈论的是哪种输入。您已将此问题标记为 Python 3,因此您无需担心使用 Python 2 和 Unicode 输入会遇到的 UnicodeEncodeErrors,但您收到的对象可以做很多事情__str__
或 __repr__
中的任何内容,几乎都会引发任何类型的异常。例如,
In [18]: import weakref
In [19]: class Foo(object): pass
In [20]: str(weakref.proxy(Foo()))
---------------------------------------------------------------------------
ReferenceError Traceback (most recent call last)
<ipython-input-20-396b2ab40052> in <module>()
----> 1 str(weakref.proxy(Foo()))
ReferenceError: weakly-referenced object no longer exists
考虑到您提出的问题,我愿意 except Exception as e:
。 Exception
是 Python 3 中的通用 "catch-all",用于 "normal" 异常(除了 "system-level" 由进程获取信号、KeyboardInterrupt
等引起的异常)。
如果我是你,我至少会记录实际的异常(e
在我上面的例子中),看看实际发生了什么(你的代码通过 except Exception:
).