在Python中,初始化Python实例变量的惯用方法是什么:
class Test:
def __init__(self, a, b, c, d):
self.a = a
self.b = b
self.c = c
self.d = d
或者
class Test2:
def __init__(self, data):
self.a = data[0]
self.b = data[1]
self.c = data[2]
self.d = data[3]
更新:我有一个名为Link的类的大约20个实例变量:
self.street
self.anode
self.bnode
self.length
self.setbackA
self.setbackB
self.bearingA
self.bearingB
self.ltype
self.lanesAB
self.leftAB
self.rightAB
self.speedAB
self.fspdAB
self.capacityAB
self.lanesBA
self.leftBA
self.rightBA
self.speedBA
self.fspdBA
self.capacityBA
self.use
每个变量都与类Link
相关。是否有推荐的重构方法?
答案 0 :(得分:4)
前者,因为它更清楚地知道参数是什么以及对象需要什么。
如果您 需要将数据作为元组传递,那么您可以使用快捷方式。而不是做后者,或类似的东西:
test = Test(data[0], data[1], data[2], data[3])
您可以解压缩列表/元组并执行:
test = Test(*data)
如果你需要传递一堆数据(超过4-5),你应该研究使用可选/关键字参数,创建一个自定义对象来保存一些数据,或使用字典:
config = Config(a, b, c, d)
test = Test(e, f, config, foo=13, bar=True)
我可能会重构你的Link类看起来像这样:
class Node(object):
def __init__(self, node, setback, bearing):
self.node = node
self.setback = setback
self.bearing = bearing
class Connection(object):
def __init__(self, lanes, left, right, speed, fspd, capacity):
self.lanes = lanes
self.left = left
self.right = right
self.speed = speed
self.fspd = fspd
self.capacity = capacity
class Link(object):
def __init__(self, street, length, ltype, use, a, b, ab, ba):
self.street = street
self.length = length
self.ltype = ltype
self.use = use
self.a = a
self.b = b
self.ab = ab
self.ba = ba
我看到你有一些重复的数据,所以将它们拉到一个单独的对象中。虽然这并没有减少你拥有的字段数量,但总的来说,它确实使你需要传递的参数更小。
拥有大量字段并不是很糟糕,但通常有大量参数。如果您可以通过将数据捆绑在一起而不需要大量参数的方式编写方法,那么您拥有的字段数并不重要。
答案 1 :(得分:2)
将一个数组打包成一堆命名变量表明你应该首先使用命名变量开始 - 坚持使用第一个。
这里只有一个原因你可能想要第二个 - 你有一些东西是无意义地产生列表而不是对象。如果确实发生了这种情况:
data = get_data_in_list_form()
actual_data = Test(*data)
您可以将部分数据分组:
self.street
self.ltype
self.use
self.length
# .a and .b can be instances of NodeConnection
self.a.setback
self.a.bearing
self.b.setback
self.b.bearing
self.b.node
# .ab and .ba can be a separate class, "UniDirectionalLink
self.ab.lanes
self.ab.left
self.ab.right
self.ab.speed
self.ab.fspd
self.ab.capacity
self.ba.lanes
self.ba.left
self.ba.right
self.ba.speed
self.ba.fspd
self.ba.capacity
这里没有必要在构造函数中执行所有操作:
link = (
Link(street=..., ltype=..., use=..., length=...)
.starting_at(node_a, bearing=..., setback=...)
.finishing_at(node_b, bearing=..., setback=...)
.forward_route(lanes, left, right, speed, fspd, capacity)
.reverse_route(lanes, left, right, speed, fspd, capacity)
)