美文网首页
类造就万物-面向对象二

类造就万物-面向对象二

作者: 那些年追过的Python | 来源:发表于2019-05-07 15:44 被阅读0次

    上一章节主要阐述了类相关的概念和创建类的基本语法,我们知道类是由数据属性和函数属性结合的,由类可以产生对象,这个过程也叫做实例化,我们得到的结果就是实例,所以实例就是对象,是由类这样一个模板所产生的,那么既然实例(对象)是由类产生的,问题来了,请问实例是否能使用类的数据属性和函数属性呢,我们带着这个问题来一步一步学习

    • 类的数据属性和函数属性在什么地方被存储?

    我们知道如何去定义一个类,如下:

    class Person:
        x = 1   #数据属性
        def func(self):  #函数属性
            pass
    

    我们定义了一个Person类,其中包含了数据属性x和函数属性func,那么这些属性被存储在什么地方,下面介绍一个变量叫属性字典,这个字典就将类的数据属性和函数属性存储起来,具体的操作如下:

    print(Person.__dict__)  #类名.__dict__
    

    通过上述方式就能访问属性字典,我们会得到如下结果

    {'__module__': '__main__', 'x': 1, 'func': <function Person.func at 0x02D30228>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
    

    我们可以看到无论是函数属性还是数据属性,在字典中的变成了键,并且键的类型是字符串,如果你只想得到访问函数属性,操作如下

    print(Person.__dict__['func'])
    

    值得注意的是我们的键必须是字符串

    • 实例(对象)如何由类产生?

    我们知道实例是由类产生的,产生过程叫做实例化,那如何产生,语法如下

    class Person:
        x = 1   #数据属性
        def func(self):  #函数属性
            pass
    p = Person()  ---> 实例化过程,此时p就是Person的一个实例
    

    一个类可以产生多个实例,比如

    class Person:
        x = 1   #数据属性
        def func(self):  #函数属性
            pass
    p1 = Person()  
    p2 = Person()
    p3 = Person()
    

    每一个实例都是独立,前面我们说到类属性字典,而实例是类产生而来,那么实例也应该有属性字典,没错实例也有自己的属性字典,我们可以访问实例的属性字典,看一看实例的属性字典中存储的是什么值

    class Person:
        x = 1   #数据属性
        def func(self):  #函数属性
            pass
    p = Person() 
    print(p.__dict__)
    打印结果
    {}
    

    打印结果为空表明,确实存在实例属性字典,但是x,func并不属于实例的属性,x,func是类属性,它们是归类所有的,所以实例是否可以使用这个属性呢,答案是肯定的

    class Person:
        x = 1   #数据属性
        def func(self):  #函数属性
            pass
    p = Person() 
    print(p.x)
    打印结果
    1
    

    print(p.x)是为了去找实例p中x属性,虽然在实例的属性字典中无法找到,但是在类属性字典能够找到,那么就打印,就好比函数的作用域,内层找不到就去外层找。所以当实例去调用某个属性的时候,如果在自己的属性字典中找不到就会去类属性字典中找。

    • 实例和类之间的关系

    类和实例的关系

    比如我们创建一个中国人的类,首先中国人所共有的属性是国籍中国,所以就把共有的属性放在类属性中。实例是由类产生的,上图中由一个类产生了3个实例,那么每个实例都是一个人,所以每个人都有姓名和年龄对吧,而姓名、年龄就应该是实例属性,存在于每个实例自己的属性字典中,这样实例与实例之间才是互补干扰的,另外,函数speak也是中国人所有共有的动作,那么也是放在类的属性字典中,但是每个实例可以取调用这个函数,那么问题来了我们怎么给实例加上实例自己的属性呢,下面就介绍如何给实例添加属性

    • 给实例添加属性(init方法)

    实例属性和类属性是独立,但是在访问实例属性时,如果找不到,那么就会去类里面找,现在init方法就是给初始化实例属性的,比如我们有一个需求

    1.定义一个类Person,类属性country = “China”
    2.生成1个实例,实例要有姓名和年龄

    首先定义一个Person类十分简单

    class Person:
        country = "China"
    

    按照要求我们要给生成一个实例,并且加上年龄和姓名属性

    p1=Person()
    p1.name="ww"
    p1.age=12
    

    此时我们去打印实例属性字典可看到结果

    print(p1.__dict__)
    结果
    {"name":"ww","age":12}
    

    说明我们已经将属性添加到了实例p1上,那么问题来了-->我现在要产生第二个实例,怎么操作,如下:

    p2=Person()
    p2.name="ww"
    p2.age=12
    print(p2.__dict__)
    

    当然打印的结果是一样的,但是发现我们在重复的做一件事情就是给实例添加属性,此时如果我们在定义类的时候,实现一个init方法,那么就可以简化操作,具体实现代码如下:

    class Person:
        country = "China"
        def __init__(self,name,age):
            self.name=name
            self.age=age
    

    init方法接收的第一个参数是self,其实在这里我们已经能够看书self是什么了,就是实例,此时我们在进行是实例化的时候,我们就直接把name 和age传给类

    p1 = Person("ww",12)  --->自动执行__init__方法,将"ww"传给name,将12传给age
    

    此时我们就可以通过init方法来初始化我们的实例属性,同时我们也可以看到此时实例属性也被添加到自己的属性字典中。

    相关文章

      网友评论

          本文标题:类造就万物-面向对象二

          本文链接:https://www.haomeiwen.com/subject/pqconqtx.html