Python 如何决定何时引入新类型而不是使用列表或元组?

Python 如何决定何时引入新类型而不是使用列表或元组?,python,Python,我喜欢用python做一些愚蠢的事情,比如解决编程难题、编写小脚本等等。每次在某个时刻,我都会面临一个两难境地:是应该创建一个新类来表示我的数据,还是只使用quick和dirty,并将所有值打包在一个列表或元组中。由于极度懒惰和个人对self关键字的厌恶,我通常选择第二个选项 我理解,从长远来看,用户定义的数据类型更好,因为path.minu cost和point.x,point.y比path[2]和point[0],point[1]更具表现力。但是,当我只需要从一个函数返回多个内容时,我觉得工

我喜欢用python做一些愚蠢的事情,比如解决编程难题、编写小脚本等等。每次在某个时刻,我都会面临一个两难境地:是应该创建一个新类来表示我的数据,还是只使用quick和dirty,并将所有值打包在一个列表或元组中。由于极度懒惰和个人对
self
关键字的厌恶,我通常选择第二个选项

我理解,从长远来看,用户定义的数据类型更好,因为
path.minu cost
point.x,point.y
path[2]
point[0],point[1]
更具表现力。但是,当我只需要从一个函数返回多个内容时,我觉得工作量太大了

所以我的问题是,在选择何时创建用户定义的数据类型以及何时使用列表或元组时,好的经验法则是什么?或者也许有一种我不知道的灵巧的蟒蛇方式


谢谢。

这当然是主观的,但我会尽量遵守最小意外的原则

如果返回的值描述对象的特征(如示例中的
point.x
point.y
),那么我将使用一个类

如果它们不是同一个对象的一部分,(比如说
返回min,max
),那么它们应该是一个元组。

您知道吗?()

或者更有效地说

Point = collections.namedtuple('Point', 'x, y')
def getLocation(stuff):
    return Point(x, y)

namedtuple
可以通过索引(
point[0]
)访问,也可以像
tuple
一样解包(
x,y=point
),因此它提供了一个几乎无痛的升级路径。

首先,关于表达性的观察。您提到过关注
point.x
point.y
point[0],point[1]
的相对表达能力,但这是一个可以通过多种方式解决的问题。事实上,对于一个简单的
结构,我认为有一个论点认为类是过度杀伤力的,特别是当您可以这样做的时候:

x, y = get_point(foo)
我想说,这和点.x,
点.y
一样有表达力;它也可能更快(无论如何,比普通类要快——没有
\uuuuu dict\uuuuu
查找),并且非常可读,假设tuple只包含几个项

我决定是否将某些内容放入类的方法更多地与我在整个程序中使用数据的方式有关:我问自己“这是一种状态吗?”如果我知道一些数据会发生很大变化,需要存储在一个地方,并由一组专门构建的函数进行操作,那么我知道数据可能是一种状态,我至少应该考虑把它放到课堂上。另一方面,如果我有一些数据不会改变,或者是短暂的,一旦我处理完就应该消失,它可能不是state,也可能不需要进入类


当然,这只是一条经验法则;例如,我可以考虑一些情况,在这些情况下,您可能需要某种“记录”类型,这样您就可以在没有15个不同的局部变量的情况下操作相当复杂的数据集合(因此存在)。但通常,如果您只操作其中的一个或两个,那么最好创建一个只接受一个或两个值并返回一个或两个值的函数,对于这一点,元组或列表是非常好的

self
实际上不是一个关键字,只是一个普通的变量名。强烈建议您在任何情况下都坚持使用它,但实际上您可以使用例如
\uu
而不是
self
。我认为如果您要使用两次或更多次程序,最好将其写入一个类。此外,您可以继承
namedtuple
中的类Foo(namedtuple(“BaseFoo”,“ham spam”),这节省了编写一些构造函数样板的时间。
x, y = get_point(foo)