• 【python基础】python类的成员变量与成员函数的一些疑问


    1. python类的成员函数为什么都要有self参数?

    在定义类的过程中,无论是显式创建类的构造方法,还是向类中添加实例方法,都要求将 self 参数作为方法的第一个参数。例如,定义一个 Person 类:

    class Person:
    	# 类的构造方法
        def __init__(self):
            print("正在执行构造方法")
        # 定义一个study()实例方法
        def study(self,name):
            print(name,"正在学Python")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    事实上,Python 只是规定,无论是构造方法还是实例方法,最少要包含一个参数,并没有规定该参数的具体名称。之所以将其命名为 self,只是程序员之间约定俗成的一种习惯,遵守这个约定,可以使我们编写的代码具有更好的可读性(大家一看到 self,就知道它的作用)。

    self 参数的具体作用是 代表 类实例化出的对象的地址。目的是 让每个类对象 只能调用 自己的类变量和类方法

    如果你接触过其他面向对象的编程语言(例如 C++),其实 Python 类方法中的 self 参数就相当于 C++ 中的 this 指针。

    也就是说,同一个类可以产生多个对象,当某个对象调用类方法时,该对象会把自身的引用作为第一个参数自动传给该方法,换句话说,Python 会自动绑定类方法的第一个参数指向调用该方法的对象。如此,Python解释器就能知道到底要操作哪个对象的方法了。

    若是去掉self参数,则会报这个错:TypeError: 类成员方法名() takes no arguments (1 given)

    2. 为何调用类的成员函数,你不必给self赋值?

    例子说明:
    创建了一个类MyClass,实例化MyClass得到了MyObject这个对象,然后调用这个对象的方法MyObject.method(arg1,arg2) ,这个过程中,Python会自动转为Myclass.mehod(MyObject,arg1,arg2)

    这就是Python的self的原理了。

    即使你的类的方法不需要任何参数,但还是得给这个方法定义一个self参数,虽然我们在实例化调用的时候不用理会这个参数,不用给它赋值。

    3. 类变量在不同位置定义有什么区别?

    (1)类变量

    类体中、所有函数之外:此范围定义的变量,称为类属性类变量

    所有类的实例化对象都同时共享类变量,也就是说,类变量在所有实例化对象中是作为公用资源存在的(通过类名修改类变量的值,会影响所有的实例化对象)。类方法的调用方式有 2 种,既可以使用类名直接调用,也可以使用类的实例化对象调用(不推荐,见最后阐述)。

    (2)实例变量

    类体中,所有函数内部:以“self.变量名”的方式定义的变量,称为实例属性实例变量

    其特点是只作用于调用方法的对象。另外,实例变量只能通过对象名访问,无法通过类名访问。

    (3)局部变量

    类体中,所有函数内部:以“变量名=变量值”的方式定义的变量,称为局部变量

    通常情况下,定义局部变量是为了所在类方法功能的实现。需要注意的一点是,局部变量只能用于所在函数中,函数执行完成后,局部变量也会被销毁

    class CLanguage :
        name = "xxx"  #类变量
        add = "http://"  #类变量
        def __init__(self):
            self.name = "C语言中文网"   #实例变量
            self.add = "http://c.biancheng.net"   #实例变量
        # 下面定义了一个say实例方法
        def say(self):
            self.catalog = 13  #实例变量
    clang = CLanguage()
    #修改 clang 对象的实例变量
    clang.name = "python教程"
    clang.add = "http://c.biancheng.net/python"
    print(clang.name)
    print(clang.add)
    
    clang2 = CLanguage()
    print(clang2.name)
    print(clang2.add)
    #输出类变量的值
    print(CLanguage.name)
    print(CLanguage.add)
    
    
    程序运行结果:
    	python教程
    	http://c.biancheng.net/python
    	C语言中文网
    	http://c.biancheng.net
    	xxx
    	http://
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    注意:

    • 通过类对象是无法修改类变量的值的,本质其实是给 clang 对象新添加 name 和 add 这 2 个实例变量。
    • 类中,实例变量和类变量可以同名,但这种情况下使用类对象将无法调用类变量,它会首选实例变量,这也是不推荐“类变量使用对象名调用”的原因。

    4. 实例方法、静态方法和类方法区别?

    具体区别和用法可阅读 blog

    (1)实例方法

    通常情况下,在类中定义的方法默认都是实例方法。不仅如此,类的构造方法理论上也属于实例方法,只不过它比较特殊。

    实例方法最大的特点就是,它最少也要包含一个 self 参数,用于绑定调用此方法的实例对象(Python 会自动完成绑定)。实例方法通常会用类对象直接调用

    class CLanguage:
        #类构造方法,也属于实例方法
        def __init__(self):
            self.name = "C语言中文网"
            self.add = "http://c.biancheng.net"
        # 下面定义了一个say实例方法
        def say(self):
            print("正在调用 say() 实例方法")
    
    
    调用方法:
    clang = CLanguage()
    clang.say()#类名调用实例方法,需手动给 self 参数传值
    clang = CLanguage()
    CLanguage.say(clang)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    (2)类方法

    Python 类方法和实例方法相似,它最少也要包含一个参数,只不过类方法中通常将其命名为 cls,Python 会自动将类本身绑定给 cls 参数(注意,绑定的不是类对象)。也就是说,我们在调用类方法时,无需显式为 cls 参数传参

    和 self 一样,cls 参数的命名也不是规定的(可以随意命名),只是 Python 程序员约定俗称的习惯而已。

    类方法需要使用@classmethod修饰符进行修饰。

    class CLanguage:
        #类构造方法,也属于实例方法
        def __init__(self):
            self.name = "C语言中文网"
            self.add = "http://c.biancheng.net"
        #下面定义了一个类方法
        @classmethod
        def info(cls):
            print("正在调用类方法",cls)
    
    
    调用方式:
    #使用类名直接调用类方法
    CLanguage.info()
    #使用类对象调用类方法(不推荐!!!)
    clang = CLanguage()
    clang.info()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    (3)静态方法

    静态方法,其实就是我们学过的函数,和函数唯一的区别是,静态方法定义在类这个空间(类命名空间)中,而函数则定义在程序所在的空间(全局命名空间)中。

    静态方法没有类似 self、cls 这样的特殊参数,因此 Python 解释器不会对它包含的参数做任何类或对象的绑定。也正因为如此,类的静态方法中无法调用任何类属性和类方法

    静态方法需要使用@staticmethod修饰。

    像有些 和类紧密相关的外部处理函数 可以 当作静态函数封装到类中。

    class CLanguage:
        @staticmethod
        def info(name,add):
            print(name,add)
    
    
    调用方式:
    #使用类名直接调用静态方法
    CLanguage.info("C语言中文网","http://c.biancheng.net")
    #使用类对象调用静态方法
    clang = CLanguage()
    clang.info("Python教程","http://c.biancheng.net/python")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    java计算机毕业设计仁爱公益网站源码+数据库+系统+lw文档+mybatis+运行部署
    MATLAB符号运算
    C++强制类型转换操作符
    QGIS地理信息系统教程:GIS分析基础
    【Java 进阶篇】JDBC ResultSet 类详解
    无涯教程-Android - List View函数
    PostgreSQL逻辑复制解密
    基础组件-流量回放平台设计
    Jetson AGX Orin 平台移植ar0233-gw5200-max9295相机驱动
    威班11月份PMP模拟考试实录
  • 原文地址:https://blog.csdn.net/All_In_gzx_cc/article/details/126975978