2017-03-18 105 views
0

我是Python新手,现在才开始看到self的用法,并想知道我是否正确使用它。我在下面有一些示例代码,想知道是否有人可以浏览一下,看看它是否是正确的用法。我不确定是否正确,因为我似乎需要使用self很多,但也许这只是语言的风格。谢谢Python:我是否正确使用“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

你不应该用Python编写getter和setter。 –

+0

@ juanpa.arrivillaga我还会如何获得/更改值?还是“自我”变量是公开的? – Ryan

+1

我相信他们总是公开的。 – Scovetta

回答

6

您正确使用self。与其他语言如C++相比,它在Python中似乎很多,其中this参数是隐含的。

但是,在Python中,并不是所有的东西都写传统的get()set()方法。你可以通过删除代码来减少你的代码 - 并在这个过程中删除很多self

4

那么,首先关闭你的__init__是错误的。 Python不允许在同一名称空间中使用相同名称的函数/方法的两个定义,无论原型是否不同。我建议你下探先定义和改变def线,在第二至:

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

这将做你想要的(让你通过使用默认值不带参数初始化)。

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

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

和用户将继续读它,仿佛它是一个简单的属性,他们真不敢(他们可以直接写_x,但那是他们的问题; Python的哲学是我们都是成年人,如果你忽略下划线前缀的约定是内部实现细节,结果就在你的头上)。

否则,是的,你会提到很多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