不同程序员在遇到问题,解决问题的思维模式。
面向过程编程(穷人思想)
基本语法,逻辑
函数式编程(小资思想)
掌握函数(遇到问题先想想有没有一个已经存在的函数具备解决这个问题的能力,如果有直接调用;没有就创建一个这样的函数)。
面向对象编程(富豪思想)
类、对象(变量、函数)
什么是类和对象
类就是拥有相同功能和相同属性的对象的集合(类就是类型、类别)。抽象的概念。
对象就是类的实例、类具体的表现。
人是类,具体的一个人就是它的对象,比如周深、我自己
电脑是类,桌上的电脑杯子是类,我的杯子
list是类,[10,20]是列表的对象
定义类(创建类)
用代码来描述清楚这个类是拥有哪些相同功能和哪些相同属性的对象的集合。
功能:用函数来描述。
属性:保存数据的变量。
语法🌸:
class 类名:
类的说明文档
类的内容
结构说明:
| 结构 | 说明 |
|---|---|
| class | 关键字;固定写法 |
| 类名 | 程序员自己命名;采用驼峰式命名并且首字母大写。(类名大写开头;驼峰式指从第二个单词开始首字母大写) |
| : | 固定写法 |
| 类的说明文档 | 多行注释 |
| 类的内容 | 相同功能和相同属性。由方法(对象方法、类方法、静态方法)和属性(对象属性、类属性)组成。 |
方法:定义在类中的函数。
属性:定义在类中的变量。
class Person:
"""人类"""
num = 12 # num是属性
def eat(self): # eat是方法
print('吃饭')
def sleep(self):
print('睡觉')
创建对象
语法🌸:
类名() 创建指定类对应的一个对象,并且将对象返回
p1 = Person()
p2 = Person()
print(p1) #<__main__.Person object at 0x000001881ACD9A88>
print(p2) #<__main__.Person object at 0x000001881ACDB288>
方法:定义在类中的函数,用来描述具备的功能。
类中的方法有三种:对象方法、类方法、静态方法。
| 对象方法 | 类方法 | 静态方法 | |
|---|---|---|---|
| 定义 | 将函数直接定义在类中 | 定义函数前加装饰器’@classmethod’ | 定义函数前加装饰器’@staticmethod’ |
| 调用 | 通过对象 | 通过类 | 通过类 |
| 特点 | 自带参数self,通过对象调用对象方法的是参数self不需要传参,系统自动将当前对象传给self(self,谁调用就指向谁) | 自带参数cls,调用的时候不需要传参,系统自动将当前类传给cls | 没有特点 |
| 式子 | 对象.xxx() | 类.xxx() | 类.xxx() |
| 使用场合 | 实现函数的功能需要用到对象属性 | 实现函数的功能不需要用到对象属性需要用到类 | 实现函数的功能既不需要用到对象属性也不需要用到类 |
例子🍙:
class A:
def func1(self):
print('对象方法')
@classmethod
def func2(cls):
print('类方法')
@staticmethod
def func3():
print('静态方法')
a = A()
# 通过对象调用对象方法
a.func1()
# 通过类调用类方法
A.func2()
# 通过类调用静态方法
A.func3()
魔法方法:方法名以’_ _ ’ 开头并且以’_ _'结尾的自带的方法。
所有的魔法方法都会在特定的情况下被自动调用。
常用的魔法方法:
_ _ repr _ _ 方法
打印对象的时候,会自动调用对象对应的类中的_ _ repr _ _ 方法,来定制打印规则(函数的返回值是什么,对象打印结果就是什么)。
返回值必须是字符串!!!
class A:
def __repr__(self):
return 'abc'
a = A()
print(a) #abc
_ _ init _ _ 方法
每次创建类的对象的时候会自动调用类中的_ _ init _ _ 方法。
class B:
def __init__(self):
print('init方法')
b1 = B() #init方法
b2 = B() #init方法
在类中添加_ _ init _ _ 方法的时候,除了方法名和方法类型不能动,可以随意添加参数和随意添加函数体。
class C:
def __init__(self, x, y):
print('C的init方法', x, y)
c = C(1, 2) #C的init方法 1 2
创建类的对象的时候需不需要参数,需要几个参数,有类中_ _ init _ _ 方法决定。
属性分为对象属性和类属性两种。
| 类属性 | 对象属性 | |
|---|---|---|
| 怎么创建 | 类中直接定义一个变量 | 以’self.属性名=值’的形式定义在类的_ _ init _ _ 方法中 |
| 怎么使用 | 通过类 | 通过对象 |
| 什么时候用 | 属性值不会随对象不同而改变 | 属性值会随对象不同而改变 |
| 式子 | 类.属性名 | 对象.属性名 |
例子🍙:
class A:
# x是类属性
x = 100
# name和age是对象属性
def __init__(self):
self.name = '小米'
self.age = 18
# 使用类属性
print(A.x)
# 修改类属性的值
A.x = 200
print(A.x)
a = A()
# 使用对象属性
print(a.name, a.age) #小米 18
# 修改对象属性的值
a.name = '小瓜'
a.age = 20
print(a.name, a.age) #小瓜 20
类中实现函数功能的时候如果需要的数据是属性,不需要提供额外的参数。
如果需要类属性直接用类来提供。
如果需要对象属性用self来提供。
🌰练习:定义一个圆的类,拥有属性:半径和圆周率,拥有的方法:求周长和求面积
class Circle:
PI = 3.14
def __init__(self):
self.radius = 1
def perimeter(self):
return 2 * Circle.PI * self.radius
def area(self):
return Circle.PI * (self.radius ** 2)
a = Circle()
print(a.perimeter())
print(a.area())
a.radius = 3
print(a.perimeter())
print(a.area())
对象属性赋初始值的方式
class Person:
def __init__(self, name, gender='男'):
self.name = name # 使用没有默认值的参数来赋值
self.age = 1 # 赋固定值
self.gender = gender # 使用没有默认值的参数来赋值
p1 = Person('小米')
print(p1.name, p1.age, p1.gender)
p2 = Person('苦瓜', '女')
print(p2.name, p2.age, p2.gender)
🌰练习:创建一个矩形类
class Squareness:
def __init__(self, length, width):
self.length = length
self.width = width
def perimeter(self):
return (self.length + self.width) * 2
def area(self):
return self.length * self.width
def __repr__(self):
# return f'长度:{self.length},宽度:{self.width}'
# return str(self.__dict__)
return f'<{str(self.__dict__)[1:-1]}>'
a = Squareness(1, 2)
print(a.perimeter(), a.area())
print(a) #{'length': 1, 'width': 2}
在面向对象编程的时候,可以直接使用对象来代替字典。
对象的对象属性支持增删改查。
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)
1)查(获取属性值)
| 调用式子 | 特点 |
|---|---|
| 对象.属性 | 获取指定属性的值,属性不存在报错 |
| getattr(对象,属性名) | 获取指定属性的值,属性不存在报错 |
| getattr(对象,属性名,默认值) | 获取指定属性的值,属性不存在返回默认值 |
print(stu1.name)
print(getattr(stu1, 'name'))
2)增、改
| 调用式子 | 特点 |
|---|---|
| 对象.属性=值 | 当属性存在的时候修改指定属性的值;当属性不存在的时候给对象添加属性 |
| setattr(对象,属性名,值) | 当属性存在的时候修改指定属性的值;当属性不存在的时候给对象添加属性 |
attr相关函数可以动态操作对象属性。
print(stu1) # {'name': '小明', 'age': 12, 'score': 67}
stu1.age = 22
print(stu1) # {'name': '小明', 'age': 22, 'score': 67}
stu1.gender = '男'
print(stu1) # {'name': '小明', 'age': 22, 'score': 67, 'gender': '男'}
setattr(stu1, 'study_id', '001')
print(stu1) # {'name': '小明', 'age': 22, 'score': 67, 'gender': '男', 'study_id': '001'}
setattr(stu1, 'score', '76')
print(stu1) # {'name': '小明', 'age': 22, 'score': '76', 'gender': '男', 'study_id': '001'}
# attr相关函数可以动态操作对象属性
# value = input('请输入你想要查看的属性:')
# # print(stu1.value)
# print(getattr(stu1, value))
3)删
| 调用式子 |
|---|
| del 对象.属性 |
| delattr(对象,属性名) |
print(stu1) # {'name': '小明', 'age': 22, 'score': '76', 'gender': '男', 'study_id': '001'}
del stu1.age
print(stu1) # {'name': '小明', 'score': '76', 'gender': '男', 'study_id': '001'}
delattr(stu1, 'name')
print(stu1) # {'score': '76', 'gender': '男', 'study_id': '001'}
4)判断是否存在
| 调用式子 |
|---|
| hasattr(对象,属性名) |
print(hasattr(stu1, 'name')) # False
print(hasattr(stu1, 'score')) # True
if not hasattr(stu1, 'name'):
stu1.name = '小明'
什么是继承
让子类直接拥有父类的属性和方法。
父类就是一个大的类,子类是这个大的类下面的一个小的分类。
继承的语法🌸
class 类名(父类):
类的说明文档
类的内容
注意:定义类的时候如果没有写父类,这个类默认继承object(基类)
class Students: == class Students(object)
class A:
a = 100
def __init__(self):
self.c = 10
self.b = 20
def func1(self):
print('对象方法')
@classmethod
def func2(cls):
print('类方法')
@staticmethod
def func3():
print('静态方法')
class B(A):
pass
print(B.a) #100
b1 = B()
print(b1.b, b1.c) #20 10
b1.func1() #对象方法
B.func2() #类方法
B.func3() #静态方法
子类添加内容
子类在拥有父类的属性和方法的同时,往往需要有属于自己特有的一些属性和方法。
1)添加类属性和方法
直接在子类中定义新的类属性和新的方法。
2)添加对象属性
需要在子类的_ _ init _ _ 方法中通过super()去调用父类的_ _ init _ _ 方法来继承父类的对象属性。
def __init__(self):
super().__init__() #调用当前类的父类的_ _ init _ _()
self.d = 24