mmx669 2021-12-18 02:53 采纳率: 94.4%
浏览 37
已结题

python中,self参数怎么理解

问题遇到的现象和发生背景

在创建的类中,定义的行为 setName中的self和name怎么理解,两个都是关键词参数吗? self.name = name,这一句是什么意思,参数在它们之间是怎么传递的?

问题相关代码,请勿粘贴截图
class Ball:
    def setName(self,name):
        self.name = name
    def kick(self):
        print("我叫%s,┗|`O′|┛ 嗷~~,谁踢我?!" % self.name)
a = Ball()
a.setName("飞火流星")
b =Ball()
b.setName("团队之星")
c = Ball()
c.setName("土豆")
a.kick()
我叫飞火流星,┗|`O′|┛ 嗷~~,谁踢我?!
b.kick()
我叫团队之星,┗|`O′|┛ 嗷~~,谁踢我?!
c.kick()
我叫土豆,┗|`O′|┛ 嗷~~,谁踢我?!



运行结果及报错内容
我的解答思路和尝试过的方法
我想要达到的结果
  • 写回答

3条回答 默认 最新

  • Hann Yang 全栈领域优质创作者 2021-12-18 08:03
    关注

    self不是关键字,可以用其它的合法变量名替换self,但是,规范和标准建议我们一致使用self。
    还有,类变量的初始化一般都用__init__()方法:

    class Ball:
        def __init__(self,name):
            self.name = name
        def kick(self):
            print("我叫%s,┗|`O′|┛ 嗷~~,谁踢我?!" % self.name)
            
    a = Ball("飞火流星")
    b = Ball("团队之星")
    
    a.kick()
    b.kick()
    

    在网上搬来一些阅读材料,供参考:
    1、self是什么
    在python的类中self代表实例本身,具体来说,是该实例的内存地址。
    在调用实例的方法时,Python解释器会自己把实例!!变量!!传给类的函数中的self。
    以上述代码I为例,代码I定义了一个类Test,在这个类中,self为参数变量,在类Test实例化得到实例ins时,python解释器自动调用__init__,执行Test.init(ins, 123),该self可接收实例ins的内存地址,从而self代表了实例本身。类似的,如果实例化ins后,执行ins.fun1( ),python解释器会将ins.fun1( )解释成Test.fun1(ins)。可见,self这个变量是无需用户手动传送值的,解释器会自动帮我们给其传递实例。
    需要注意的是,self不是关键字,换言之,可以用其它的合法变量名替换self,但是,规范和标准建议我们一致使用self。
    2、self的使用场景
    在类中,self的使用有下面3个场景:
    1)self为类中的函数的第一个参数,例如在类中,def fun1(self, …)。
    “在调用实例的方法时,Python解释器会自己把实例变量传给类的函数中的self”,如果类的函数的第一个参数不是代表实例的self,则调用实例的方法时,该方法没有参数接收解释器自动传入的实例变量,从而程序会产生异常。
    事实上,“和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数”(廖雪峰老师说的)。
    2)在类中,引用实例的属性,示例:self.变量名(如self.val0)。
    引用实例的属性的目的是为实例绑定属性、写入或读取实例的属性。
    例如,在代码I中,在类的函数__init__中,“self.val1 = val1”将属性val0绑定到了实例self(类实例化成ins后,self就代表实例ins了)上,并且将变量val1的值赋给了实例的属性val0。在函数fun1中,print(self.val0),读取了实例self的值val0,并打印出来,当然,在函数中修改属性val0的值也是可以的。
    3)在类中,调用实例的方法,例如,self.fun1();获取实例的方法的地址,例如self.fun1。
    类是抽象的模板,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。既然,self代表实例,则可以“self.函数名”的方式表示实例的方法地址,以“self.函数名()”的方式,调用实例的方法。在类的定义中,以及实例化后对实例方法的调用,都可以这样做。
    3、python的几种变量——按作用域分
    全局变量:在模块内、在所有函数外面、在class外面,这就是全局变量。
    局部变量:在函数内、在class的方法内(未加self修饰的) ,这就是局部变量
    静态变量(也可以说,类属性):在class内的,但不在class的方法内的,这就是静态变量
    实例变量(也可以说,实例属性):在class的方法内的,用self修饰的变量,这就是实例变量
    4、self和变量的关系
    综合上述的1、2和3点,可以得到在类中,self和变量的关系了,一言以蔽之,被self修饰的变量是实例变量,不被self修饰的变量不是实例变量。
    实例变量有什么作用,或者说,什么时候应该使用self修饰变量比较好?我的总结如下:
    当我们想将某个变量绑定给实例时,就在类中,使用self修饰该变量。一般来说,类实例化为不同实例后,为了不同实例的某一变量互不干扰,就将该变量绑定给实例。
    具体的使用场景,
    1)若需要在类的不同方法中调用同一变量,且属于同一个类的不同实例的该变量互不影响(即排除类属性),则在类中将该变量绑定给实例。
    2)需要在类实例化得到实例后,修改、或引用实例的某变量,则在类中将该变量绑定给实例。

    img

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 12月29日
  • 已采纳回答 12月21日
  • 创建了问题 12月18日

悬赏问题

  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示