我一直主要用Java编程,我发现Pythons明确地自我引用类成员是丑陋的。我真的不喜欢所有“自我”如何使我的方法变得混乱,所以我发现自己想要将实例变量存储在局部变量中以便摆脱它。例如,我会替换它:
def insert(self, data, priority):
self.list.append(self.Node(data, priority))
index = len(self)-1
while self.list[index].priority < self.list[int(index/2)].priority:
self.list[index], self.list[int(index/2)] = self.list[int(index/2)], self.list[index]
index = int(index/2)
用这个:
def insert(self, data, priority):
l = self.list
l.append(self.Node(data, priority))
index = len(self)-1
while l[index].priority < l[int(index/2)].priority:
l[index], l[int(index/2)] = l[int(index/2)], l[index]
index = int(index/2)
通常我会将局部变量命名为与实例变量相同,但是“list”是保留的,所以我选择了“l”。我的问题是:这在Python社区被认为是不好的做法吗?
答案 0 :(得分:2)
首先更容易回答。在Python中,下划线用于避免与关键字和内置函数冲突:
list_ = self.list
这将被Python程序员理解为正确的方式。
至于为属性创建局部变量,它取决于。使用Plone(甚至是标准库)的代码库,显示使用x = self.x,尤其是
context = self.context
正如评论中指出的那样,它可能容易出错,因为将另一个值绑定到局部变量不会影响该属性。
另一方面,如果某个属性在方法中是只读的,则会使代码更具可读性。因此,如果变量使用足够局部就可以了,比如说,就像函数式编程语言中的let-clauses一样。
有时属性实际上是函数,因此每次都会计算self.property。 (另一个问题是“pythonic”如何对属性获取者进行大量计算)(感谢Python @property versus getters and setters为一个现成例子):
class MyClass(object):
...
@property
def my_attr(self):
...
@my_attr.setter
def my_attr(self, value):
...
总之,谨慎使用,谨慎使用,不要成为规则。
答案 1 :(得分:1)
我同意明确地添加“self”(或“this”用于其他语言)并不是很吸引眼球。但正如人们所说,python遵循“显性优于隐性”的理念。因此,它真的希望您表达您想要访问的变量的范围。
Java不允许您使用未声明的变量,因此不存在混淆的可能性。但是在python中如果“self”是可选的,对于赋值a = 5
,不清楚是创建成员还是局部变量。因此,某些地方需要明确的self
。访问虽然会起作用。请注意,Java也需要明确的this
来进行名称冲突。
我只计算了我的一些意大利面条代码中的self
s。对于1000行代码,self
出现的次数超过500次。现在代码确实不那么可读,但问题不在于重复使用self
。对于上面的代码示例:第二个版本的行长度较短,这使得理解起来更容易和/或更快。我想说你的例子是可以接受的案例。