Python - 在本地变量中存储实例变量以避免“自我”的不良做法?

时间:2015-11-05 17:37:56

标签: python

我一直主要用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社区被认为是不好的做法吗?

2 个答案:

答案 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。对于上面的代码示例:第二个版本的行长度较短,这使得理解起来更容易和/或更快。我想说你的例子是可以接受的案例。