• python 面向对象与类的基本知识


    一  什么是面向对象,面向对象与类的关系。

      面向对象的程序设计是用来解决扩展性。

      面向过程:根据业务逻辑从上到下写垒代码

      函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可

      面向对象:对函数进行分类和封装,让开发“更快更好更强...”

      简单的来说,如果程序的功能都是由类和对象来实现的,那么就是面向对象编程了。

    二 对象与类的关系

      对象是特征与技能的结合体。

      类是一系列对象共同的特征与技能的结合体。

    三 类的基本格式

    class People:
        def __init__(self):
            pass
        def foo(self):
            pass
        def bar(self):
            pass

      这就定义了一个People类。

    四 类的说明

      1.类的定义:关键字 class

      2 实例化:类名+( ),产生一个类的对象或实例。

    class People:
        def __init__(self):
            pass
        def foo(self):
            pass
        def bar(self):
            pass
    
    p=People()
    print(p)

      输出:

    <__main__.People object at 0x000001E03DA36F60>

      3 实例化本质,调用__init__函数。

    class People:
        def __init__(self,name):
            pass
        def foo(self):
            pass
        def bar(self):
            pass
    
    p=People()
    print(p)

      输出:

    TypeError: __init__() missing 1 required positional argument: 'name'

      因为实际是调用__init__函数,有一个name参数,需要传参。

      传一个参数就ok了

    class People:
        def __init__(self,name):
            pass
        def foo(self):
            pass
        def bar(self):
            pass
    
    p=People('egon')
    print(p)

      4 类的作用

        1 实例化

        2 属性引用 __dict__方法。

    五 类与对象的namespace

      1 namespace用__dict__方法。

         是字典格式

    class People:
        def __init__(self,name):
            self.name=name
        def foo(self):
            pass
        def bar(self):
            pass
    
    p1=People('egon')
    print(People.__dict__)

      输出:

    {'__module__': '__main__', '__init__': <function People.__init__ at 0x000001E933F0ABF8>, 'foo': <function People.foo at 0x000001E933F0AF28>, 'bar': <function People.bar at 0x000001E933F26048>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}

      类的名称空间内有很多,定义的foo,bar函数,包括__init__初始化函数。

      对象的namespace

    class People:
        model='person'
        def __init__(self,name):
            self.name=name
        def foo(self):
            pass
        def bar(self):
            pass
    
    p1=People('egon')
    print(p1.__dict__)

      输出:

    {'name': 'egon'}

      对象的本身并没有动态属性(函数属性),也没有静态属性(类的数据属性),对于这两个,只有绑定关系。  对象只有属于自己的静态属性,即__init__函数初始化的数据。

      总结:类有属于自己的名称空间,每一个生成的对象也都有属于自己的名称空间。类的名称空间里有各种动态属性,静态属性,而对象的名称空间只有属于它自己的静态属性。

         对象的名称空间在类的名称空间之下。对象找不到的静态属性或者动态属性可以去类的名称空间中寻找。

         对象与类的静态属性和动态属性的关系是绑定关系。 详见第六条

      2  类和对象的名称空间都是字典,所以可以对字典进行增删改查。

        1 增

    class People:
        model='person'
        def __init__(self,name):
            self.name=name
        def foo(self):
            pass
        def bar(self):
            pass
    
    p1=People('egon')
    print(p1.__dict__)
    p1.age=35
    print(p1.__dict__)

      输出:

    {'name': 'egon'}
    {'name': 'egon', 'age': 35}

        2 改

    class People:
        model='person'
        def __init__(self,name):
            self.name=name
        def foo(self):
            pass
        def bar(self):
            pass
    
    p1=People('egon')
    print(p1.__dict__)
    p1.name='alex'
    print(p1.__dict__)

      输出:

    {'name': 'egon'}
    {'name': 'alex'}

    六 对象与类的动态属性和静态属性的关系。

      1 动态属性

    class People:
        model='person'
        def __init__(self,name):
            self.name=name
        def foo(self):
            pass
        def bar(self):
            pass
    
    p1=People('egon')
    print('对象调用foo时地址',p1.foo)
    print('类调用foo时地址 ',People.foo)

      输出:

    对象调用foo时地址 <bound method People.foo of <__main__.People object at 0x000001E5343EEBE0>>
    类调用foo时地址  <function People.foo at 0x000001E5343EAF28>

      可以看到类调用函数时 是正儿八经的函数地址,所以需要正常传值,一个参数都不能少,少了就会报错。

      对象调用函数时,对象与函数的关系是绑定关系,实现了自动传值。谁调用,就将这个对象自动传给函数的第一个参数。

       2静态属性

        首先强调的一点是:类的静态属性对象一般不要调用。

        类的静态属性是不可变类型时。

    class People:
        x=1
        def __init__(self,name):
            self.name=name
        def foo(self):
            pass
        def bar(self):
            pass
    
    p1=People('egon')
    p1.x=2
    print('p1.x:',p1.x,id(p1.x))
    print('People.x:',People.x,id(People.x))

      输出:

    p1.x: 2 1980286672
    People.x: 1 1980286640

        实际上相当去p1在自己的名称空间内新建了一个x的变量。对类的名称空间内的x 完全不一样。

      

        类的静态属性是可变类型是,对象就能够直接调用了。

    class People:
        l=[1]
        def __init__(self,name):
            self.name=name
        def foo(self):
            pass
        def bar(self):
            pass
    
    p1=People('egon')
    p1.l.append(2)
    print('p1.l:',p1.l,id(p1.l))
    print('People.l:',People.l,id(People.l))

      输出:

    p1.l: [1, 2] 2917779341960
    People.l: [1, 2] 2917779341960

    七 类与基本数据类型的关系。

    class People:
        def __init__(self,name):
            self.name=name
        def foo(self):
            pass
    p1=People('egon')
    print(type(p1))
    print(People)
    
    print(int)
    print(type(1))
    
    print(str)
    print(type('123'))

      输出:

    <class '__main__.People'>
    <class '__main__.People'>
    <class 'int'>
    <class 'int'>
    <class 'str'>
    <class 'str'>

      之前学的剧本数据类型就是本质上就是和现在学习的类是一样的。在python3中统一起来的。

      现在再来回顾基本数据类型的用法。

    l1=[1,2,3]
    l2=list([1,2,3])
    print(l1)
    print(l2)

      l2就是类的实例化过程。 类名+ ( 传参) 。

      举个例子:列表的追加

    l1=[1,2,3]
    l2=list([1,2,3])
    l1.append(4)
    list.append(l2,4)
    
    print(l1,l1.append)
    print(l2,list.append)

      输出:

    [1, 2, 3, 4] <built-in method append of list object at 0x000001B553228288>
    [1, 2, 3, 4] <method 'append' of 'list' objects>

    分析:l1 就是作为列表list的一个对象,调用列表的动态属性(函数属性),自动传值。

         l2是类调用动态属性,没有自动传值,必须手动传值。

           两者实现了同样的效果。

    八 对象的属性

      1 一开始,通过__init__方法初始化而来的

      2 在类内调用对象的属性, self.属性名

      3 在类外调用对象的属性,对象名.属性名

     九 举例

      __init__的作用,在实例化的时候就已经生效了。

    class Father:
        def __init__(self):
            self.name='bb'
        def say(self):
            print('from bb',self.name)
    class Mother:
        def __init__(self):
            self.name='mm'
        def talk(self):
            print('from mm',self.name)
    class Son(Father,Mother):
        pass
    
    s=Son()
    s.talk()

      输出:

    from mm bb

      这个例子说明:

        实例化,先执行__init__方法,以此从自己的,父类的, 多个父类时顺序找第一个有__init__方法的父类。走到这一步时,如果能找到__init__,对象已经有了自己的名称空间,如果都没有那就没有自己的名称空间。

        对象调用方法,如果自己名称空间内有,先从自己名称空间内找。

        厉害了,这个例子。

  • 相关阅读:
    Linux软件管理
    Linux计划任务与进程管理
    PHP学习 Day_04
    Linux网络管理
    单播组播的实现
    Linux 下的tmpfs文件系统(/dev/shm)
    11.Linux date命令的用法
    Luogu P3783 [SDOI2017]天才黑客
    Luogu P3768 简单的数学题
    Luogu P2336 [SCOI2012]喵星球上的点名
  • 原文地址:https://www.cnblogs.com/654321cc/p/7521264.html
Copyright © 2020-2023  润新知