我的大部分编程经验都是使用 C++。受 Bjarne Stroustrup 的演讲启发,我最喜欢的编程技术之一是“类型丰富”的编程;开发新的健壮数据类型,不仅可以通过将功能包装到类型中来减少我必须编写的代码量(例如向量加法,而不是 newVec.x = vec1.x + vec2.x; newVec.y = ... 等等,我们可以只使用 newVec = vec1 + vec2) 但也会在编译时通过强类型系统揭示代码中的问题。
我最近在 Python 2.7中进行的一个项目需要具有上限和下限的整数值。我的第一直觉是创建一个新的数据类型(类),它的行为与 python 中的普通数字相同,但始终在其(动态)边界值内。
class BoundInt:
def __init__(self, target = 0, low = 0, high = 1):
self.lowerLimit = low
self.upperLimit = high
self._value = target
self._balance()
def _balance(self):
if (self._value > self.upperLimit):
self._value = self.upperLimit
elif (self._value < self.lowerLimit):
self._value = self.lowerLimit
self._value = int(round(self._value))
def value(self):
self._balance()
return self._value
def set(self, target):
self._value = target
self._balance()
def __str__(self):
return str(self._value)
这是一个好的开始,但它需要像这样访问这些 BoundInt 类型的内容
x = BoundInt()
y = 4
x.set(y) #it would be nicer to do something like x = y
print y #prints "4"
print x #prints "1"
z = 2 + x.value() #again, it would be nicer to do z = 2 + x
print z #prints "3"
我们可以在类中添加大量python的“魔术方法”定义来增加一些功能:
def __add__(self, other):
return self._value + other
def __sub__(self, other):
return self._value - other
def __mul__(self, other):
return self._value * other
def __div__(self, other):
return self._value / other
def __pow__(self, power):
return self._value**power
def __radd__(self, other):
return self._value + other
#etc etc
现在代码的大小正在迅速爆炸式增长,并且对正在编写的内容有大量重复,而回报却很少,这似乎一点也不像 Python。
当我开始想从普通的 python 数字(整数?)和其他 BoundInt 对象构造 BoundInt 对象时,事情变得更加复杂
x = BoundInt()
y = BoundInt(x)
z = BoundInt(4)
据我所知,这需要在 BoundInt() 构造函数中使用相当大/丑陋的 if/else 类型检查语句,因为 python 不支持(c 样式)重载。
所有这一切都感觉非常像尝试在 python 中编写 c++ 代码,如果认真对待我最喜欢的书之一, Code Complete 2 ,这是一个大罪。我觉得我在逆流而上,而不是让它带我前进。
我非常想学习编写 python 'pythonic-ally' 的代码,解决这类问题域的最佳方法是什么?什么是学习正确 Python 风格的好资源?