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())


相关文章
|
8月前
|
缓存 供应链 芯片
电子元件类商品 item_get - 商品详情接口深度分析及 Python 实现
电子元件商品接口需精准返回型号参数、规格属性、认证及库存等专业数据,支持供应链管理与采购决策。本文详解其接口特性、数据结构与Python实现方案。
|
测试技术 Python
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
795 31
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
|
人工智能 Python
[oeasy]python083_类_对象_成员方法_method_函数_function_isinstance
本文介绍了Python中类、对象、成员方法及函数的概念。通过超市商品分类的例子,形象地解释了“类型”的概念,如整型(int)和字符串(str)是两种不同的数据类型。整型对象支持数字求和,字符串对象支持拼接。使用`isinstance`函数可以判断对象是否属于特定类型,例如判断变量是否为整型。此外,还探讨了面向对象编程(OOP)与面向过程编程的区别,并简要介绍了`type`和`help`函数的用法。最后总结指出,不同类型的对象有不同的运算和方法,如字符串有`find`和`index`方法,而整型没有。更多内容可参考文末提供的蓝桥、GitHub和Gitee链接。
348 11
|
存储 C语言 Python
[oeasy]python077_int类型怎么用_整数运算_integer_进制转化_int类
本文主要讲解了Python中`int`类型的应用与特性。首先回顾了`int`词根的溯源,探讨了整型变量的概念及命名规则(如匈牙利命名法)。接着分析了整型变量在内存中的存储位置和地址,并通过`type()`和`id()`函数验证其类型和地址。还介绍了整型变量的运算功能,以及如何通过`int()`函数将字符串转化为整数,支持不同进制间的转换(如二进制转十进制)。此外,文章提及了关键字`del`的使用场景,对比了Python与C语言中`int`的区别,并总结了整型与字符串类型的差异,为后续深入学习奠定基础。
348 1
|
数据采集 存储 XML
python实战——使用代理IP批量获取手机类电商数据
本文介绍了如何使用代理IP批量获取华为荣耀Magic7 Pro手机在电商网站的商品数据,包括名称、价格、销量和用户评价等。通过Python实现自动化采集,并存储到本地文件中。使用青果网络的代理IP服务,可以提高数据采集的安全性和效率,确保数据的多样性和准确性。文中详细描述了准备工作、API鉴权、代理授权及获取接口的过程,并提供了代码示例,帮助读者快速上手。手机数据来源为京东(item.jd.com),代理IP资源来自青果网络(qg.net)。
|
Java C++ Python
Python基础---类
【10月更文挑战第10天】Python类的定义
281 2
|
索引 Python
python-类属性操作
【10月更文挑战第11天】 python类属性操作列举
194 1
|
8月前
|
数据采集 机器学习/深度学习 人工智能
Python:现代编程的首选语言
Python:现代编程的首选语言
1296 102
|
8月前
|
数据采集 机器学习/深度学习 算法框架/工具
Python:现代编程的瑞士军刀
Python:现代编程的瑞士军刀
464 104

推荐镜像

更多