Python类(class)中self的理解

简介: Python类(class)中self的理解
0. 前言

按照国际惯例,首先声明:本文只是我自己学习的理解,虽然参考了他人的宝贵见解,但是内容不乏不准确的地方,希望批评指正,共同进步。


对于Python新手(甚至部分老手)而言,在面向对象编程类(class)中,都有一个比较困扰的参数——self。


因此写作本文加强自己的理解,也帮助别人理解。


1. 从一个问题入手理解"self"

下面是一段关于class的python代码,在这段代码中完全没有"self"这个参数,请思考下这段代码中的4个"print"哪个是可以运行的,哪个会报错?


答案后面揭晓。


class test():
    def __init__(x):
        x.ten = 10

    def multi_ten(y, z):
        return z*y.ten

    def divide_ten(w, v):
        return v/w.ten

    def hello(k):
        return 'hello'

    def world():
        return 'world'

TEST = test()

print(TEST.multi_ten(9))
print(TEST.divide_ten(100))
print(TEST.hello())
print(TEST.world())
2. "self"的定义


Python规定在类(class)的方法(method)中,都必须有一个形参(parameter),而且必须是第一个形参,用于传递类的实例(instance)。而这个形参,一般约定熟成取名为"self"。


类中的函数称为方法,例如上面的multi_ten()、divide_ten()这些都是方法。在Pycharm中,在类中编写方法的时候也会自动跳出“self”这个参数。


拿上面的例子来说,在multi_ten()这个方法中,第一个形参(parameter)是"y",在test()类实例化后,它传递的实参(argument)是"TEST"实例(instance),所以这里的"y"就相当于"self"。


因为"TEST"这个实参已经传入multi_ten()这个方法中,所以"TEST"实例可以调用multi_ten(),即TEST.multi_ten()。


3. __init__()方法

__init__()本质上是一个方法,所以其实和"self"(形参)关系不大,为什么经常把这两者联系到一起呢?


因为__init__()是一个特殊的方法,每次创建类的新实例时__init__()都会自动运行,这样就可以在__init__()方法中定义以"self"为前缀的变量,例如上面的x.ten,供类中的所有方法使用。


4. 问题解析

回到最开始的问题,通过对"self"的理解,可以知道前3个print是可以运行的,最后一个会报错。

C:\Users\Lenovo\Desktop\DL\Pytest\Scripts\python.exe C:/Users/Lenovo/Desktop/DL/Pytest/test_main.py
90
10.0
hello
Traceback (most recent call last):
  File "C:\Users\Lenovo\Desktop\DL\Pytest\test_main.py", line 22, in <module>
    print(TEST.world())
TypeError: world() takes 0 positional arguments but 1 was given

Process finished with exit code 1

而其报错的原因“TypeError: world() takes 0 positional arguments but 1 was given”就是再说:在定义world()这个方法的时候,没有填位置形参(positional parameter),调用的时候应该也是给0个位置实参(positional argument),但是实际使用却给了一个位置实参(positional argument)——“TEST”,所以会报错。

5. 结语

最后再说明一下,虽然Python的类在"self"的上可以用其他变量替代,但是这种操作都是极其不推荐的,无论新手老手,在任何情况下,在"self"的位置上都应该老老实实地写成"self"。上面那段代码应该这样写:

class test():
    def __init__(self):
        self.ten = 10

    def multi_ten(self, z):
        return z*self.ten

    def divide_ten(self, v):
        return v/self.ten

    def hello(self):
        return 'hello'

    def world(self):
        return 'world'

TEST = test()

print(TEST.multi_ten(9))
print(TEST.divide_ten(100))
print(TEST.hello())
print(TEST.world())


相关文章
|
3天前
|
Python
Python 一步一步教你用pyglet制作可播放音乐的扬声器类
Python 一步一步教你用pyglet制作可播放音乐的扬声器类
14 0
|
10天前
|
Python
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(上)
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(上)
53 0
|
10天前
|
索引 Python
python 格式化、set类型和class类基础知识练习(上)
python 格式化、set类型和class类基础知识练习
33 0
|
12天前
|
Python
python学习12-类对象和实例对象
python学习12-类对象和实例对象
|
1月前
|
Python
Python类定义:从小白到专家的旅程
Python类定义:从小白到专家的旅程
8 0
|
1月前
|
Python
Python类与对象:深入解析与应用
本文介绍了Python中的核心概念——类和对象,以及它们在面向对象编程中的应用。类是用户定义的类型,描述具有相同属性和行为的对象集合;对象是类的实例,具备类的属性和方法。文章通过示例讲解了如何定义类、创建及使用对象,包括`__init__`方法、属性访问和方法调用。此外,还阐述了类的继承,允许子类继承父类的属性和方法并进行扩展。掌握这些概念有助于提升Python编程的效率和灵活性。
|
1月前
|
算法 开发者 Python
【Python 基础扫盲 】self参数、__init__方法和.__str__方法的用处和区别?
【Python 基础扫盲 】self参数、__init__方法和.__str__方法的用处和区别?
20 0
|
1月前
|
机器学习/深度学习 设计模式 开发者
python类用法(四)
python类用法(四)
18 0
|
Python
python class 初学
python class 初学 被测试的 code 我在lib目录创建一个hehe文件夹,和一个__init__空文件。把xclass(我的代码)放进去。xclass: print ('这里在执行') class Student(): def __init__(self,name,age): self.
1012 0
|
1天前
|
机器学习/深度学习 数据挖掘 API
pymc,一个灵活的的 Python 概率编程库!
pymc,一个灵活的的 Python 概率编程库!
4 1