Python:我正确使用“自我”吗?

时间:2017-03-18 04:56:41

标签: python syntax self

我是Python的新手,现在才开始看到self的用法,并想知道我是否正确使用它。我在下面有一些示例代码,并想知道是否有人可以浏览并查看它是否正确使用。我不确定它是否正确,因为我似乎需要经常使用self,但也许这只是语言的风格。谢谢

代码

from tkinter import Canvas

class BouncyBall:
    def __init__(self):
        self.x = 0
        self.y = 0
        self.d = 15
        self.color = 'blue'
        self.speed = 2
        self.move_left = False
        self.move_right = False

    def __init__(self, x, y, d, color):
        self.x = x
        self.y = y
        self.d = d
        self.color = color
        self.speed = 2
        self.move_left = False
        self.move_right = False

    #Accessor Methods
    def get_x(self):
        return self.x
    def get_y(self):
        return self.y
    def get_diameter(self):
        return self.d
    def get_color(self):
        return self.color
    def get_speed(self):
        return self.speed
    def moving_right(self):
        return self.move_right
    def moving_left(self):
        return self.move_left

    #Mutator Methods
    def set_x(self, x):
        self.x = x
    def set_y(self, y):
        self.y = y
    def set_diameter(self, d):
        self.d = d
    def set_color(self, color):
        self.color = color
    def set_speed(self, speed):
        self.speed = speed
    def set_move_right(self, move_right):
        self.move_right = move_right
    def set_move_left(self, move_left):
        self.move_left = move_left

    def draw_ball(self, canvas):
        if isinstance(canvas, Canvas):
            canvas.create_oval(self.x, self.y, self.x + self.d, self.y + self.d, fill=self.color)
        else:
            print("Improper Parameter Sent In")

2 个答案:

答案 0 :(得分:6)

您正在使用self。与C ++等隐含this参数的其他语言相比,它在Python中往往会出现很多。

但是,在Python中,为所有内容编写get()set()方法并不常见,正如您所做的那样。您可以通过删除代码来减少代码 - 并在此过程中删除大量self

答案 1 :(得分:4)

好吧,首先关闭__init__是错误的。无论原型是否不同,Python都不允许在同一名称空间中使用相同名称的函数/方法的两个定义。我建议删除您的第一个定义,并将第二个定义的def行更改为:

def __init__(self, x=0, y=0, d=15, color='blue'):

将执行您想要的操作(允许您使用默认值初始化不带参数)。

您可能还想放弃所有set_get_方法。如果属性是读/写,只需正常访问它们而不需要getter和setter。如果稍后您需要将它们设置为只读或计算它们,则可以将属性重命名为具有前导下划线(例如_x)并使用@property装饰器继续提供类似属性的属性访问(有或没有可写性)。这将立即删除绝大多数(不必要的)访问器和mutator方法,使您经常引用self。例如,如果x应该是只读的,那么您需要在self._x = x中设置__init__,然后定义一个属性:

@property
def x(self):
    return self._x

并且用户会继续阅读它,好像它是一个简单的属性,他们只是不能意外地写它(他们可以直接写_x,但这是他们的问题; Python& #39;哲学是我们所有的成年人,如果你忽略了强调前缀是内部实施细节的惯例,后果就在你的头上。

否则,是的,您将大量引用self。 Python更喜欢显式命名空间到隐式,因此您使用self来区分实例访问和范围变量访问。如果您将要使用给定的变量(并且在方法过程中它不会发生变化),您可以将其缓存到本地名称并使用不合格的本地名称,例如:

 def some_method(self):
     # We use x a lot and never change it, so cache up front:
     x = self.x

     # Can read cached x over and over without qualification for rest of method