类造就万物-面向对象二

2019-05-07  本文已影响0人  那些年追过的Python

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

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

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方法就是给初始化实例属性的,比如我们有一个需求

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方法来初始化我们的实例属性,同时我们也可以看到此时实例属性也被添加到自己的属性字典中。

上一篇下一篇

猜你喜欢

热点阅读