1. 编程思想
程序员在遇到问题解决问题的思维模式
-
面向过程编程(穷人思想) - 基本语法,逻辑
-
函数式编程(小资思想) - 掌握函数 (遇到问题先想想有没有一个已经存在的函数具备解决这个问题的能力,如果有直接调用。没有就创建一个这样的函数
-
面向对象编程(富豪思想) - 类、对象(变量、函数)
2. 类和对象
- 什么是类、什么是对象
- 类就是拥有相同功能和相同属性的对象的集合 - 抽象的概念
- 对象就是类的实例 - 类具体的表现
- 类就是类型、类别
例如
- 人是类,具体的一个人就是它的对象,比如:小红、小明
- 电脑是类,我的桌上这台电脑
- 杯子是类,我桌上这三个杯子都是它的对象
- list是类,[10, 20]是列表的对象
-
定义类(创建类) - 用代码描述清楚这个类是拥有哪些相同功能和相同属性的集合
- 功能 - 函数
- 属性 - 保存数据的变量
class 类名: 类的说明文档 类的内容
- class - 关键字:固定写法
- 类名 - 程序员自己命名
采用驼峰式命名并且首字母大写。(类名大写开头;驼峰式-从第二个单词开始单词首字母大写) - 类的说明文档 - 多行注释
- 类的内容 - 相同功能和相同属性。
由方法(对象方法、类方法、静态方法)和属性(对象属性、类属性)组成- 方法 - 定义在类中的函数
- 属性 - 定义在类中的变量
class Person: '''人类''' num = 61 # num是属性 def eat(self): # eat是方法 print('吃饭') def sleep(self): print('睡')
-
创建对象
类名() # 创建指定类对应的一个对象,并且将对象返回
示例
p1 = Person() p2 = Person() print(p1) print(p2) # 运行结果 ''' <__main__.Person object at 0x0000029E723E2FA0> <__main__.Person object at 0x0000029E723E2850> '''
3. 类中的方法
- 方法-定义在类中的函数用,用来描述具备的功能
- 类中的方法有三种:对象方法、类方法、静态方法
方法 | 定义 | 如何调用 | 特点 | 什么时候调用 |
---|---|---|---|---|
对象方法 | 将函数直接定义在类中 | 对象.xxx() | 自带参数self,通过对象调用对象方法的是参数self不需要传参,系统自动将当前对象传给self。(self, 谁调用就指向谁) | 如果实现函数的功能需要用到对象属性就使用对象方法 |
类方法 | 定义函数前加装饰器’@classmethod’ | 类.xxx() | 自带参数cls,调用的时候不需要传参,系统自动将当前类传给cls | 如果实现函数的功能不需要对象属性需要类就是用类方法 |
静态方法 | 定义函数前加装饰器’@staticmethod’ | 类.xxx() | 没有特点 | 实现函数功能既不需要对象属性也不需要类 |
class A:
def func1(self):
print('对象方法')
@classmethod
def func2(cls):
print('类方法')
@staticmethod
def func3():
print('静态方法')
a = A()
a.func1()
A.func2()
A.func3()
# 运行结果
'''
对象方法
类方法
静态方法
'''
3.4 初始化方法
- 魔法方法
方法名以’__‘开头并且以’__'结尾的自带方法,就是魔法方法
所有的魔法方法都会特定的情况下被自动调用
- 常用的魔法方法:__init__方法、__repr__方法
-
repr方法
- 打印对象的时候会自动调用对象对应的类中的__repr__方法,来定制打印规则(函数的返回值是什么,对象打印结果就是什么)
- 返回值必须是字符串!
class A: def __repr__(self): return 'abc' pass a1 = A() print(f'a1:{a1}') # 运行结果 ''' a1:abc '''
-
__init__方法
- 每次创建类的对象的时候会自动调用类中的__init__方法
class B: def __init__(self): print('init方法') b1 = B() # 运行结果 ''' init方法 '''
- 在类中添加__init__方法的时候,除了方法名和方法类型不能动,可以随意添加参数和随意添加函数体
class C: def __init__(self, x, y): print('C的init方法', x, y) # 创建类的对象的时候需不需要参数,需要几个参数,由类中__init__方法决定 c1 = C(10, 20) # 运行结果 ''' C的init方法 10 20 '''
4. 属性
属性 | 怎么创建 | 怎么使用 | 什么时候使用 |
---|---|---|---|
类属性 | 在类中直接定义一个变量,这个变量就是类属性 | 类.xxx | 当属性值不会因为对象不同而不一样的时候就使用类属性 |
对象属性 | 以’self.属性名=值’的形式定义在类的__init__方法中 | 对象.属性名 | 当属性值会因为对象不同而不一样的时候就使用类属性 |
class A:
# x是类属性
x = 100
# name和num是对象属性
def __init__(self):
self.name = '小明'
self.num = 10
# 使用类属性
print(A.x)
# 修改类属性的值
A.x = 200
print(A.x)
a = A()
# 使用对象属性
print(a.name, a.num)
# 运行结果
'''
100
200
小明 10
'''
对象属性赋初始值的方式
class Person:
def __init__(self, name, gender='男'):
self.name = name # 使用没有默认值的参数来赋值
self.age = 1 # 赋固定值
self.gender = gender # 使用有默认值的参数来赋值
def __repr__(self):
# return f'name:{self.name}, age:{self.age}, gender:{self.gender}'
return str(self.__dict__)
p1 = Person('小明')
print(p1.name, p1.age, p1.gender)
p2 = Person('小花', '女')
print(p2.name, p2.age, p2.gender)
# 运行结果
'''
小明 1 男
小花 1 女
'''
4.3 属性的增、删、改、查
-
在面向对象編程的时候,可以直接使用对象来代替字典
class Student: def __init__(self, name, age=18, score=0): self.name = name self.age = age self.score = score def __repr__(self): return str(self.__dict__) stu1 = Student('小明', 12, 67) stu2 = Student('小花', 19, 100) print(stu1, stu2) # 运行结果 ''' {'name': '小明', 'age': 12, 'score': 67} {'name': '小花', 'age': 19, 'score': 100} '''
-
对象的对象属性支持增、删、改、查
- 查 - 获取属性值
- a.对象.属性 - 获取指定属性的值,属性不存在报错
- b.getattr(对象,属性名) - 获取指定属性的值,属性不存在报错
- c.getattr(对象,属性名,默认值) - 获取指定属性的值,属性不存在直接返回默认值
print(stu1.name) print(getattr(stu1, 'name')) # print(stu1.gender) # AttributeError: 'Student' object has no attribute 'gender' # print(getattr(stu1, 'gender')) # AttributeError: 'Student' object has no attribute 'gender' print(getattr(stu1, 'gender', '男')) # 运行结果 ''' 小明 小明 男 '''
- 增、改
- a. 对象.属性 = 值 - 当属性存在的时候修改指定属性对应的值;当属性不存在的是给对象添加属性
- b. setattr(对象, 属性名, 值) - 当属性存在的时候修改指定属性对应的值;当属性不存在的是给对象添加属性
print(stu1) stu1.age = 22 print(stu1) stu1.gender = '男' print(stu1) setattr(stu1, 'study_id', '001') print(stu1) setattr(stu1, 'score', '76') print(stu1) # 运行结果 ''' {'name': '小明', 'age': 12, 'score': 67} {'name': '小明', 'age': 22, 'score': 67} {'name': '小明', 'age': 22, 'score': 67, 'gender': '男'} {'name': '小明', 'age': 22, 'score': 67, 'gender': '男', 'study_id': '001'} {'name': '小明', 'age': 22, 'score': '76', 'gender': '男', 'study_id': '001'} '''
- 删
- del 对象.属性
- delattr(对象, 属性名)
print(stu1) del stu1.age print(stu1) delattr(stu1, 'name') print(stu1) # 运行结果 ''' {'name': '小明', 'age': 22, 'score': '76', 'gender': '男', 'study_id': '001'} {'name': '小明', 'score': '76', 'gender': '男', 'study_id': '001'} {'score': '76', 'gender': '男', 'study_id': '001'} '''
- 查 - 获取属性值
-
判断属性是否存在
-
hasattr(对象, 属性名)
print(hasattr(stu1, 'name')) print(hasattr(stu1, 'score')) if not hasattr(stu1, 'name'): stu1.name = '小明' print(hasattr(stu1, 'name')) # 运行结果 ''' False True True '''
5. 继承
-
让子类直接拥有父类的属性和方法
父类就是一个大的类,子类就是这个大类下面的一个小的分类 -
继承的语法
注意:定义类的时候如果没有写父类,这个类默认继承object(基类)class 类名(父类): 类的说明文档 类的内容
class A: a = 100 def __init__(self): self.b = 10 self.c = 20 def func1(self): print('对象方法') @classmethod def func2(cls): print('类方法') @staticmethod def func3(): print('静态方法') class B(A): pass print(B.a) x = B() print(x.b, x.c) x.func1() B.func2() B.func3() # 运行结果 ''' 100 10 20 对象方法 类方法 静态方法 '''
-
子类添加内容
子类在拥有父类的属性和方法的同时,往往需要由属于自己特有的一些属性和方法
-
添加类属性和方法
直接在子类中定义新的类属性和新的方法 -
添加对象属性
需要在子类的__init__方法中通过super()去调用父类的__init__方法来继承父类的对象属性class C(A): m = 11 def __init__(self): super().__init__() # 调用当前类的父类的__init__() self.name = '小明' def func11(self): print('C的对象方法') @classmethod def func22(cls): print('C的类方法') @staticmethod def func33(): print('C的静态方法') def func1(self): print('C的对象方法2') print(C.a, C.m) x = C() print(x.name) print(x.b, x.c) # 运行结果 ''' 100 11 小明 10 20 '''