为什么我在每个方法调用上都传递一个参数?

问题描述

我不必通过 self,但我必须在代码的第 4 行中通过 master

import game
window = game.Window()
cluster = game.Cluster(window)
cluster.circle(**window**,10,5)


. . .
class Cluster(Window):
    def __init__(self,master):
        self.obj = []
        self.x = []
        self.y = []
        self.hitBox = master.canvas.create_rectangle(0,0)
    def update(self,master):
        master.canvas.coords(self.hitBox,min(self.x)-2,min(self.y)-2,max(self.x)+2,max(self.y)+2)
    def circle(self,master,x,y,r):
        self.obj += [master.canvas.create_oval(x-r,y-r,x+r,y+r)]
        self.x += [x-r,x+r]
        self.y += [y-r,y+r]
        self.update(master)

解决方法

更改您的代码以将 master 的值存储为实例属性:

class Cluster(Window):
    def __init__(self,master):
        self.obj = []
        self.x = []
        self.y = []
        self.hitbox = master.canvas.create_rectangle(0,0)
        self.master = master

    def update(self):
        self.master.canvas.coords(self.hitbox,min(self.x)-2,min(self.y)-2,max(self.x)+2,max(self.y)+2)

    def circle(self,x,y,r):
        self.obj += [self.master.canvas.create_oval(x-r,y-r,x+r,y+r)]
        self.x += [x-r,x+r]
        self.y += [y-r,y+r]
        self.update()

因此您不必将其传递给每个方法。

self 在 Python 中得到特殊处理并且它被隐式传递 (https://docs.python.org/3/tutorial/classes.html#classes):

在 C++ 术语中,通常类成员(包括数据成员)是公共的(除了见下文私有变量),并且所有成员函数都是虚拟的。与 Modula-3 一样,从对象的方法中引用对象的成员也没有简写:方法函数是用表示对象的显式第一个参数声明的,该参数由调用隐式提供。和 Smalltalk 一样,类本身也是对象。这为导入和重命名提供了语义。与 C++ 和 Modula-3 不同,内置类型可以用作用户扩展的基类。此外,就像在 C++ 中一样,大多数具有特殊语法的内置运算符(算术运算符、下标等)都可以为类实例重新定义。

更严格地说:第一个参数 - 从技术上讲,您可以随意命名(https://docs.python.org/3/tutorial/classes.html#random-remarks):

通常,方法的第一个参数称为 self。这只不过是一个约定:名称 self 对 Python 绝对没有特殊意义。但是请注意,如果不遵循约定,您的代码对其他 Python 程序员来说可能不太可读,并且可以想象,编写的类浏览器程序可能依赖于这样的约定。