第11课 类和对象(2019-12-03)

一、“类”有关的知识

1. 面向对象程序设计(OPP,Object-Oriented Programming):是一种计算机编程架构,它认为程序由一系列的对象组成。其中最核心的概念是类和对象,类是对现实世界的抽象,类的实例被称为对象。

1) 中心思想:一切皆对象(Everything is an object.)

2)OPP = 对象+类+继承+多态+消息

3)主要目标:重用性、灵活性、扩展性

2. 类:是一种用户定义的数据类型,就像基本的数据类型byte、int、float等一样,不同的是它是一种复杂的数据类型。类可以用来定义变量,创建对象,还可以派生子类。

3. 每个类都包含了数据说明、一组用于操作数据或传递数据的函数。

4. 因为类的本质是一种数据类型,而不是数据。所以类不存在于内存中,不可以被直接操作,只有被实化为对象时,才会变得可操作。

5. 类的内部封装了属性和方法,即成员数据和成员函数。它描述一个对象能够做什么,以及做的方法。

6. Python支持面向对象的三大特征:封装、继承和多态。子类继承父类,同样可以继承到父类的变量和方法。

二、定义类

1. 定义类的语法如下:

class 类名:

执行语句

零到多个类变量

零到多个类方法

例如:

#定义一个Person类

>>> class Person:

’这是一个学习定义类的案例‘ # 类的说明文档,放在类头和头体之间

#定义一个类变量

hair ='black'

#定义一个构建方法

def __init__(self,name='Jeff',age=8): # 两个变量都有默认值

self.name=name

self.age=age

#定义一个实例方法

def say(self,content):

print(content)

2. 类名:从语法上讲只要是一个合法的标识符即可,但要考虑程序的可读性,类名要求是由一个或多个有意义的单词组成,每个单词的首字母大写,单词和单词之间不用任何人分隔符。

3. 定义类需要注意的几点:

1)定义类和定义函数类似,只是类用class关键字,函数用def关键字。

2)类头包含了class关键字和类名,对冒号(:)作为类的开始,类体包含了类变量和方法,如果不为类定义任意变量和方法,则为一个空类,用pass作为占位符。例如:

>>>class Empty:

pass

3) 类所包含的类变量可以动态的增加或删除。程序也可以为已有的对象增加或删除实例变量。

4)在类中定义的方法默认是实例方法,定义实例方法和定义函数基本想同,实例方法至少应该定义一个参数,该参数通常被命名为self。

三、创建对象

1. 创建对象:调用某个类的方法,即可创建这个类的对象。例如:

#接上面的代码

#将类的Person对象赋值给变量p

>>>p=Person()

2. 创建完对象,就可以使用该对象了。Python的对象有如下作用:

1)操作对象的实例变量:访问实例变量的值,增加、修改、删除实例变量。

#接上面的代码

#直接输出对象p的实例变量name 和 age的值

>>> print(p.name,p.age)  #结果:Jeff 8

#访问p的实例变量name ,给它重新赋值

>>>p.name='Mary'

2)操作对象的方法:调用方法,添加或删除方法。

#调用P的say()方法

p.say('welcome to yanghang robot')

#再次输出对象p的实例变量name 和 age的值

>>>print(p.name,p.age) #结果:Mary 8

3. 对象的动态性:

1)动态增加或删除对象的实例变量,例如;

# 直接给对象的变量赋值就可以增加变量

>>> p.skills=['dancing','swimming']

>>> print(p.skills)  #结果: ['dancing', 'swimming']

#使用del语句,就可以删除对象的变量

>>> del p.name

>>> print(p.name)

#结果报错:AttributeError: 'Person' object has no attribute 'name'

2)动态的增加和删除方法,例如:

#P对象动态增加的方法不会自行绑定第一个参数self

#先定义一个函数 info()

>>> def info(self): p

print('--info--函数',self)

# 使用info() 函数给 对象p 的方法赋值,就动态增加了方法

>>> p.info=info

>>> p.info(p)  #程序必需手动传入参数

# 使用lambda表达式 给 对象p 的方法赋值,就动态增加了方法

>>> p.bar= lambda self: print('---lambda---',self)

>>> p.bar(p) #程序必需手动传入参数

4. 方法之间的依赖:

1) 类体中方法的第一个参数self, 会被自动绑定给对象,所以不需要给第一个参数传值。

2) 方法的第一个参数所代表的对象是不确定的,也就是谁调用该方法,第一个参数就代表谁。例如:

#定义一个dog类

>>> class dog:

#定义一个jump方法

def jump(self):

print('jump......')

#定义一个run方法,run方法调用了jump方法

# run 和 jump 之间就存在依赖

def run (self):

self.jump()

print('run.......')

3)在构造方法中,self参数代表该构建方法正在初始化的对象。

四、类方法和静态方法

1. 方法:是类或对象的行为特征的抽象, Python中方法其实也是函数,所以其定义方法和调用形式都和函数类似。

2. 使用类调用方法:之前的例子都是对象调用方法,如果类直接调用方法,就不会自动绑定self参数,所以要手动传入参数,例如:

#定义一个类user

>>> class user:

#定义一个方法 walk

def walk(self):

print(self,'walking....')

#使用类直接调用方法

>>> user.walk()

#结果报错:TypeError: walk() missing 1 required positional argument: 'self'

#手动传入参数值'abc'

>>> user.walk('abc')

# 结果:abc walking....

3. 类方法和静态方法的区别:

1)类方法的第一个参数会自动绑定到类本身;而静态方法不会绑定到类。

2)使用@classmethod修饰的方法是类方法;使用@staticmethod修饰的方法为静态方法。例如:

#定义一个bird类

>>> class bird:

#用@classmethod修饰类方法fly

@classmethod

def fly(cls):

print('类方法fly',cls)

#用@staticmethod修饰静态方法info

@staticmethod

def info(p):

print('静态方法info',p)

#类直接调用 类方法fly,不需要传入参数

>>> bird.fly() #结果:类方法fly

#类调用info方法,需要手动传入参数

>>> bird.info('abc') #结果: 静态方法info abc

# 构建对象和调用方法

>>> b=bird

>>> b.fly()

>>> b.info('abc')

4. @函数装饰器

1)@classmethod和@staticmethod就是函数装饰器,classmethod和 staticmethod都是Python内置的函数。

2)使用@符号引用已有的函数,可以用来修饰其它函数。我们也可以开发自定义的函数修饰器。

3)当一个函数装饰另一个函数时,实际上是完成了以下两步:

被装饰的函数B, 作为参数被传给了@符号所引用的函数A

将函数B替换成了上一步的返回值,所以函数B已经不是原来的函数。

>>> def funA(fn):

print('A')

 return 'Jeff'

>>> @funA  #装饰的效果相当于funA(funB),将funB做为了funA的参数,返回了'Jeff'

def funB():

print('B')

>>> print(funB)

# funB已经不再是一个函数,而是一个字符串,运行结果Jeff

六、本节回顾

1) 关于类的知识你知道了哪些?

2)如何定义一个类?

3)如何构建类的对象和使用对象?

4)如何添加、删除、修改方法?

5)类方法和静态方法的区别?

6)@函数装饰器的用法?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容