我来自静态类型编程,我有兴趣了解动态类型编程背后的基本原理,以检查动态类型语言是否能更好地满足我的需求。
我读过鸭子编程背后的理论。我还读到,单元测试(在静态类型编程中是可取的和使用的)在动态语言中变得需要,其中缺少编译时检查。
然而,我仍然不敢错过大局。特别是,如何检查变量类型被意外更改的错误?
让我们在Python中做一个非常简单的例子:
#! /usr/bin/env python
userid = 3
defaultname = "foo"
username = raw_input("Enter your name: ")
if username == defaultname:
# Bug: here we meant userid...
username = 2
# Here username can be either an int or a string
# depending on the branch taken.
import re
match_string = re.compile("oo")
if (match_string.match(username)):
print "Match!"
Pylint,pychecker和pyflakes不会就此问题发出警告。
处理这类错误的Pythonic方法是什么?
代码是否应该使用try / catch包装?
答案 0 :(得分:0)
这不会在编译时给你检查,但正如你建议使用try / catch,我会假设运行时检查也会有所帮助。
如果使用类,可以在__setattr__
方法中挂钩自己的类型检查。例如:
import datetime
# ------------------------------------------------------------------------------
# TypedObject
# ------------------------------------------------------------------------------
class TypedObject(object):
attr_types = {'id' : int,
'start_time' : datetime.time,
'duration' : float}
__slots__ = attr_types.keys()
# --------------------------------------------------------------------------
# __setattr__
# --------------------------------------------------------------------------
def __setattr__(self, name, value):
if name not in self.__slots__:
raise AttributeError(
"'%s' object has no attribute '%s'"
% (self.__class__.__name__, name))
if type(value) is not self.attr_types[name]:
raise TypeError(
"'%s' object attribute '%s' must be of type '%s'"
% (self.__class__.__name__, name,
self.attr_types[name].__name__))
# call __setattr__ on parent class
super(MyTypedObject, self).__setattr__(name, value)
这将导致:
>>> my_typed_object = TypedObject()
>>> my_typed_object.id = "XYZ" # ERROR
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 28, in __setattr__
TypeError: 'MyTypedObject' object attribute 'id' must be of type 'int'
>>> my_typed_object.id = 123 # OK
您可以继续使上面的TypedObject
更通用,以便您的类可以继承它。
另一个(可能更好)解决方案(指出here)可能是Entought Traits