• Python--面向对象


    一 : 类和对象

      类:具有相同属性和技能的一类事物.

      对象: 具体的类的表现,具体的实实在在的一个实例.

      举例说明 : 人和猫都是动物,那么动物就是一个类,人和猫就是两个对象.

    二 : 定义和组成

      通过关键字class定义一个类,通过类名()的形式生成一个对象,这个行为称作实例化.

    class className():
        类的内容

      类的内容分为两部分:变量部分和函数(方法)部分.下面看一个Person类,类名的首字母都要大写

    class Person:
        mind = '有思想'  
        animal = '高级动物'
        faith = '有信仰'
    
        def __init__(self,name,age,hobby):
            self.name = name  
            self.age = age
            self.hobby = hobby
    
        def work(self):  
            print('%s都会工作...' %self.name)
    
        def shop(self):
            print('人类可以消费....')

      mind,animal,faith都是静态变量,__init__(),work(),shop()三个是定义在类中的方法,称作普通方法.

    三 : 使用一个类

      在一个类中,可以直接使用静态变量,比如在类中(方法外)print一下一个变量,是完全可以的;对于普通方法,需要将类实例化之后用获得的对象来调用普通方法.

      在类的外面,可以通过  类名.变量名  的方法获得变量的值, 同样的方法也可以调用类里的普通方法,不过需要传入一个参数,不过这种调用方法的方式不推荐.

    print(Person.mind, Person.animal, Person.faith) # 有思想 高级动物 有信仰
    Person.shop('asfdsf') # 人类可以消费....

      将类实例化之后,可以通过对象或者类中的变量,调用类中的方法.

    a = Person('rubby', 10, 'sleeping')
    print(a.mind, a.animal, a.faith) # 有思想 高级动物 有信仰
    a.work() #rubby会工作...
    a.shop() #人类可以消费....

      不仅仅可以获得值,我们还可以进行修改和删除:

    print(a.mind) # 有思想
    a.mind = '没智商'
    print(a.mind) # 没智商
    print(Person.mind) # 有思想
    del a.mind
    print(a.mind) # 有思想

      这个现象需要从内存的角度来解释 : 当创建了一个类之后,内存中会出现一个属于这个类的空间,其中储存着类中的静态变量/方法名/方法的内存地址(类的方法具体是储存在类外面的),实例化之后,类外面单独为这个对象创建了一个空间,其中储存着属于对象的变量和一个指向创建它的类的指针,从对象的角度是无法修改类中的变量的值的,所以第二行只是在对象的空间里创建了一个名为mind的变量,它的值为'没智商',这时打印对象的mind,解释器会先去对象空间中找是否存在名为mind的变量,如果找到了就用它,所以这时打印类中的mind和对象的mind会得到不同的值,当使用del删除对象空间的mind之后,因为解释器从对象空间中找不到,就去所属的类中找,所以这时的mind就是类中的mind的值了.

      为了佐证,我们另外给对象赋一个值abc:

    a.abc = 'abc'
    print(a.abc) # abc
    print(Person.abc) # 报错 AttributeError: type object 'Person' has no attribute 'abc'

      变量abc只存在于对象的空间里.

      除了使用万能的  .  的方法,还可以使用__dict__()这个函数获得类或者对象的空间有哪些东西:

    print(Person.__dict__) #{'__module__': '__main__', 'mind': '有思想', 'animal': '高级动物', 'faith': '有信仰', '__init__': <function Person.__init__ at 0x000001FC5DA88268>, 'work': <function Person.work at 0x000001FC5DA882F0>,
        # 'shop': <function Person.shop at 0x000001FC5DA88378>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
    print(a.__dict__) # {'name': 'rubby', 'age': 10, 'hobby': 'sleeping', 'abc': 'abc'}

      可以看到,类中除了定义的三个变量和三个方法外,还有__module__,__dict__,__weakref__三个方法和__doc__一个变量,而对象a中除了实例化的时候传入的name,age,hobby三个变量外,还有我们后来加的abc变量.

    四 : 类的初始化

      对于类中定义的三个方法,从名字中我们就可以看出__init__()方法和work(),shop()两个方法的不同,这个方法就是初始化方法--初始化(Initialization).

      如果在其中加入一行,让他打印一行字,我们看会有什么效果:

      

        def __init__(self,name,age,hobby):
            self.name = name  #  Person.money = '运用货币'
            self.age = age
            self.hobby = hobby
            print('喵喵喵')
            print(self)
    
    p = Person('rubby', 10, 'sleeping') #喵喵喵 #<__main__.Person object at 0x000001FFDCB8B780>

      可以看到,我们进行实例化的时候就打印了喵喵喵和一个地址,而且这个方法我们没有主动调用它,这说明这个方法是在类实例化对象的时候自动触发的,他的作用就是给这个对象进行初始化设置.

      那么在实例化的时候究竟发生了什么呢?

      主要有以下三步: 1. 为对象开辟一个空间 2.将对象的地址和括号中的参数传入__init__()方法,其中地址是自动传且必须传的,别的参数作为位置参数传入,然后在该方法中进行初始化 3. 将初始化完成的对象传给变量p.

      在__init__方法的 参数中,第一个总是接收地址的,形参名没有强制性的命名,但是作为一种规范,大家都使用self.初始化的过程就是给这个self附加各种属性的过程,为了方便,我们把self中的存储name的变量也命名为name,self.name = name这一行中,左边的name是当场给self的一个属性命名为name,等号右边的name则是形参name,这个必须要知道.

  • 相关阅读:
    Longest Valid Parentheses
    Gas Station
    Multiply Strings
    LeetCode:Merge Sorted Array
    LeetCode:Single Number II
    LeetCode: Single Number
    LeetCode:3Sum
    LeetCode:Binary Tree Preorder Traversal
    LeetCode: Best Time to Buy and Sell Stock III
    LeetCode: Best Time to Buy and Sell Stock II
  • 原文地址:https://www.cnblogs.com/DoingBe/p/9433489.html
Copyright © 2020-2023  润新知