#3 Python面向对象(二)

发布时间:2019-05-13 22:01:24编辑:auto阅读(1970)

    前言

    上一节主要记录面向对象编程的思想以及Python类的简单创建,这节继续深入类中变量的相关知识,Here we go!

    Python中类的各种变量

    1.1 类变量

    类变量定义:在类中,在函数体(方法)外的变量称为类变量。类变量在整个类中是公用的

    类变量初始化:按照以上定义,类变量的初始化如下

    1 class Doctor:
    2     '''
    3     类变量的初始化
    4     '''
    5     salary = 100  # salary为类变量
    6 
    7     def talk():
    8         print('I am a doctor')

    类变量访问:因为类变量在整个类中是公用的,所以在不同的环境下都能访问。在类中函数体外直接使用 类变量 访问;在类中函数体内使用 类.类变量 或者 实例.类变量 访问;在类外使用 类.类变量 或者 实例.类变量访问

    class Doctor:
        '''
        在类中函数体外访问类变量salary
        '''
        salary = 100
        print(salary)
    
        def talk(self):
            print('I am a doctor')
    
    
    lisi = Doctor()   # 一旦实例化后,就会自动按顺序执行类中函数体外的代码
    
    
    # 运行结果:
    100
    class Doctor:
        '''
        在类中函数体内访问类变量salary
        '''
        salary = 100
    
        def talk0(self):
            '''
            使用类.类变量访问
            '''
            print('My salary is {0}'.format(Doctor.salary))
    
        def talk1(self):
            '''
            使用实例.类变量访问
            '''
            print('My salary is {0}'.format(self.salary))
    
    
    lisi = Doctor()
    
    lisi.talk0()
    lisi.talk1()
    
    
    # 运行结果:
    My salary is 100
    My salary is 100
    class Doctor:
        '''
        在类外访问类变量salary
        '''
        salary = 100
    
        def talk(self):
            print('I am a doctor')
    
    
    lisi = Doctor()
    print(Doctor.salary)  # 使用 类.类变量 访问
    print(lisi.salary)   # 使用 实例.类变量 访问
    
    
    # 运行结果:
    100
    100

    1.2 实例变量

    实例变量定义:在类中,在函数体(方法)内的变量称为实例变量。

    实例变量初始化:按照上面定义,实例变量的初始化如下

    1 class Doctor:
    2     '''
    3     初始化实例变量
    4     '''
    5 
    6     def talk(self):
    7         self.sentence = 'I am man'    # self.sentence 为实例变量

    实例变量访问:实例变量在整个类中并不是公用的,所以其访问范围有限。在类中函数体内使用 实例.实例变量 访问;在类外使用 实例.实例变量 访问

    class Doctor:
        '''
        类中函数体内的访问
        '''
    
        def talk(self):
            self.sentence = 'I am man'    # 初始化实例变量self.sentence
            print(self.sentence)   # 访问实例变量
    
    
    lisi = Doctor()
    
    lisi.talk()  # 调用talk方法
    
    
    # 运行结果:
    I am man
    class Doctor:
        '''
        类外访问实例变量
        '''
    
        def talk(self):
            self.sentence = 'I am man'    # 初始化实例变量self.sentence
    
    
    lisi = Doctor()
    
    lisi.talk()  # 必须先执行talk方法才能访问talk方法里面的实例变量
    print(lisi.sentence)  # 类外访问实例变量

    1.3 类变量、实例变量与全局变量、局部变量的异同点

    在Python基础教程中讲解了全局变量与局部变量的相关知识,本节提到的两个变量与它们有什么异同呢?

    • 绝对来说,类变量与实例变量都是局部变量

    • 相对来说,在类中,类变量相当于全局变量,但实例变量并不相当于局部变量,更不相当于全局变量

    • 相对来说,在实例中,类变量和实例变量都相当于全局变量

    • 相对来说,在类中的方法里,才有局部变量,初始化的时候不是定义 实例.实例变量 ,而是直接定义 变量 

     一下子说的这么复杂难以理解,举个栗子🌰就明白了:

    class Doctor:
        salary = 100
    
        def talk(self):
        ¦   print('I am a doctor')
    
    
    print(salary)
    
    # salary是Doctor的类变量,在类中定义
    # 但在主程序中并不能被正确访问
    # 因为salary变量是局部变量
    
    
    # 运行结果:
    Traceback (most recent call last):
      File "8.py", line 8, in <module>
        print(salary)
    NameError: name 'salary' is not defined
    
    # 抛出变量未定义异常
    class Doctor:
        def talk(self):
            self.salary = 100
    
    
    print(salary)
    
    # 同样,实例变量self.salary也是局部变量
    
    
    # 运行结果:
    Traceback (most recent call last):
      File "9.py", line 6, in <module>
        print(salary)
    NameError: name 'salary' is not defined
    
    # 抛出变量未定义异常
    class Doctor:
        def talk(self):
            self.salary = 100
    
    
    Doctor().talk()
    print(salary)
    
    # 即使执行了talk方法,也不能正确访问
    # 因为它至始至终都是局部变量
    
    # 运行结果:
    Traceback (most recent call last):
      File "9.py", line 12, in <module>
        print(salary)
    NameError: name 'salary' is not defined
    class Doctor:
        salary = 100
        print(salary)
    
        def talk(self):
            print(Doctor.salary)
    
        def eat(self):
            print(Doctor.salary)
    
    
    lisi = Doctor()
    lisi.talk()
    lisi.eat()
    
    # 因为类变量在整个类中都是共有的
    # 因此类变量能被类中的方法访问
    # 换句话说,在类中类变量相当于全局变量

    # 运行结果:

      100
      100
      100

    class Doctor:
        salary = 100
        print(salary)
    
        def talk(self):
            self.food = 'BaoZi'
            print(Doctor.salary)
            print(self.food)
    
        def eat(self):
            print(Doctor.salary)
            print(self.food)
    
    
    lisi = Doctor()
    lisi.talk()
    lisi.eat()
    
    # 在talk方法里面定义实例变量self.food
    # 但是在eat方法里面却可以访问self.food这个实例变量
    #(前提是必须先运行talk方法,就相当于初始化self.food)
    # 因此,在实例中,类变量和实例变量都相当于全局变量
    
    
    # 运行结果:

      100
      100
      BaoZi
      100
      BaoZi

     

    class Doctor:
    
        def talk(self):
            salary = 100
            print(salary)
    
        def eat(self):
            print(salary)
    
    
    lisi = Doctor()
    lisi.talk()
    lisi.eat()
    
    # 在类中talk方法里定义局部变量salary
    # 在其他方法中是不能被访问的
    
    
    # 运行结果:
    100
    Traceback (most recent call last):
      File "12.py", line 13, in <module>
        lisi.eat()
      File "12.py", line 8, in eat
        print(salary)
    NameError: name 'salary' is not defined

    1.4 类变量和实例变量注意事项

    「类变量在类中函数体内有两种访问方式: 类.类变量 和 实例.类变量 ,这两种方式会带来不同的后果。使用 实例.类变量 访问类变量后,其实是重新创建了一个新的实例变量: 实例.实例变量 ,与类变量已经无关了」

    class Doctor:
        salary = 100  # 初始化类变量salary
    
        def talk0(self):
            print('talk0:', Doctor.salary)
            Doctor.salary = 200   # 修改类变量salary的值为200
    
        def talk1(self):
            print('talk1:', Doctor.salary)
            print('talk1:', self.salary)
            self.salary = 300   # 修改self.salary的值为300
    
        def talk2(self):
            print('talk2:', self.salary)
            print('talk2:', Doctor.salary)  # 输出的类变量并没有被改变为300
    
    
    lisi = Doctor()
    
    lisi.talk0()
    lisi.talk1()
    lisi.talk2()
    
    
    # 运行结果:
    talk0: 100
    talk1: 200
    talk1: 200
    talk2: 300
    talk2: 200

    强烈建议:类变量的访问方法用 类.类变量 

    小结

    本小节介绍了Python中类的各种变量知识,在实际使用中要有深刻的理解才行。之后会记录类的传参、类的性质、类的属性方法等,拜拜~~

关键字