01 认识类和对象
1. 编程思想
- 面向过程编程: 穷人思想 (基本语法、分支、循环、逻辑思维)
- 函数式编程: 小资思想 (基本语法、分支、循环、逻辑思维、函数)
- 面向对象编程: 富豪思想 (基本语法、分支、循环、逻辑思维、函数、类、对象)
# 求10的阶乘
s = 1
for i in range(1, 11):
s *= i
print(s)
def factorial(n):
s = 1
for i in range(1, n+1):
s *= i
return s
2.什么是类,什么是对象
-
类就是具有相同功能和相同属性的对象的集合。(类是一个抽象的概念)
-
对象就是类的实例(某一类事物的具体表现)
电脑是类,桌上那台电脑是电脑的对象
车是类,我家那辆车是对象;汽车、工程车、出租车是车的子类(分类)
3.定义类(创建类)
用代码来描述这个类是拥有哪些相同属性和哪些相同功能的集合
数值相关的共同特点用属性来描述 属性就是定义在类变量
非数值相关的共同特点用方法来描述 方法就是定义在类中的函数
语法:
class 类名:
类的说明文档
类的内容
说明:
位置 | 作用 |
---|---|
class | 关键字; 固定写法 |
类名 | 有程序员自己命名; 必须满足两点命名要求 三个规范: a.首字母大写,采用驼峰式命名(大驼峰) StudentName b.见名知义 c.不使用系统函数、类、模块名 |
: | 固定写法 |
类的说明文档 | 多行注释 |
类的内容 | 在这儿用代码来描述这个类相同的功能和属性有哪些; 主要包含属性(对象属性、类属性)和方法(对象方法、类方法、静态方法) |
student_name (PEP8\下划线)
StudentName(大驼峰)
class Person:
"""这是人类"""
pass
4.创建类对象
语法:
类名() # 创建指定类的对象并且返回
p1 = Person()
p2 = Person()
print(p1)
print(p2)
02 类中的方法
1.方法 - 对象方法、类方法、静态方法
方法 | 怎么定义 | 怎么调用 | 特点 |
---|---|---|---|
对象方法 | 直接定义在类中的函数就是对象方法 | 以’对象.xxx()'的方式来调用 提供对象来调用对象方法 | 提供对象来调用对象方法的时候,默认参数self不需要传参,系统会自动将当前对象传给self(self是谁调用就指向谁) |
类方法 | 需要在定义函数前加"@classmethod" | 以’类.xxx()'的方式来调用 通过类来调用类方法 | 通过类来调用类方法的时候,默认参数cls不用传参,系统会自动将当前类传给cls |
静态方法 | 需要在定义函数前"@staticmethod" | 以’类.xxx’的方式来调用 通过类来调用静态方法 | 没有特点 |
1) 对象方法:
a.怎么定义: 直接定义在类中的函数就是对象方法
b.怎么调用: 以’对象.xxx()'的方式来调用 - 提供对象来调用对象方法
c.特点: 提供对象来调用对象方法的时候,默认参数self不需要传参,系统会自动将当前对象传给self(self是谁调用就指向谁)
class A:
def func1(self):
print('对象方法')
def func11(self, x):
print(self, x)
a = A()
b = A()
print(f'a: {a}')
print(f'b: {b}')
b.func1()
a.func11(100)
a.func1()
2) 类方法:
a.怎么定义: 需要在定义函数前加"@classmethod"
b.怎么调用: 以’类.xxx()'的方式来调用 - 通过类来调用类方法
c.特点: 通过类来调用类方法的时候,默认参数cls不用传参,系统会自动将当前类传给cls
class B:
@classmethod
def func2(cls):
print('类方法', cls)
print(B)
B.func2()
3) 静态方法:
a.怎么定义: 需要在定义函数前"@staticmethod"
b.怎么调用: 以’类.xxx’的方式来调用 - 通过类来调用静态方法
c.特点: 没有特点
class C:
@staticmethod
def func3():
print('静态方法')
C.func3()
03 初始化方法
1. 魔法方法
方法名由两个下划线开头同时两个下划线结尾,并且会在特定情况下自动调用的方法就是魔法方法
class A:
def __add__(self, other):
print('add被调用')
return 100
# def __str__(self):
# print('str被调用')
# return 'abc'
def __repr__(self):
print('repr被调用')
return 'abc'
a1 = A()
a2 = A()
print(a1 + a2)
print(a1)
print('-------------------------华丽的分割线--------------------------')
print(a2)
list1 = [a1, a2]
print(list1)
2. 常用的两个魔法方法
1) __init__
方法
a. 当通过类创建对象的时候,类中的__init__
方法会被自动调用
b. 在类中添加__init__
方法的时候,可以根据需要在方法中随意添加参数;如果在__init__
方法中添加了额外的参数,那么在创建这个类的对象的时候必须通过类名后面的括号来给__init__
方法提供额外的实参
class B:
def __init__(self):
print('init方法被调用')
b1 = B()
b2 = B()
class C:
def __init__(self, x, y=2):
print('C的init方法被调用', x, y)
c1 = C(10, 20)
c2 = C(x=100, y=200)
c3 = C(10)
2) __repr__
方法
a . 打印类的对象的时候会自动调用__repr__
方法,并且将这个方法的返回值作为这次打印的打印结果
b.这个方法的返回值必须是字符串。(__repr__
方法中的self指向的当前的打印对象)
class D:
def __repr__(self):
print('repr被调用')
return 'abc'
D()
04 属性
1.属性
1) 类属性
a.怎么定义: 直接定义在类中的变量就是类属性
b.怎么使用: 以’类.xxx’的方式来使用 - 通过类来使用类属性
c.什么时候用: 属性值不会因为对象不同而不一样,就定义成类属性
2) 对象属性
a.怎么定义: 以’self.属性名 = 值’的形式定义在__init__方法中
b.怎么使用: 以’对象.xxx’的方式来使用 - 通过对象来使用对象属性
c.什么时候用: 属性值会因为对象不同而不一样,就定义成对象属性
class A:
# x、m是类属性
x = 10
m = '你好'
# y和n是对象属性
def __init__(self):
self.y = 100
self.n = 'hello'
# 通过类使用类属性
print(A.x, A.m)
# 通过对象来使用对象属性
a = A()
print(a.y, a.n)
2.对象属性赋值方式
1) 直接用一个具体的数据给对象属性赋值
class Circle:
pi = 3.1415926
def __init__(self):
self.r = 10
c1 = Circle()
print(c1.r)
c1.r = 5
print(c1.r)
2) 用一个没有默认值的参数给对象属性赋值
class Circle:
pi = 3.1415926
def __init__(self, r):
self.r = r
c1 = Circle(5)
print(c1.r)
c2 = Circle(10)
print(c2.r)
3) 用一个有默认值的参数给对象属性赋值
class Circle:
pi = 3.1415926
def __init__(self, r=5):
self.r = r
# self.area = Circle.pi * r ** 2
c1 = Circle(5)
print(c1.r)
# print(c1.area)
c2 = Circle(10)
print(c2.r)
# print(c2.area)
- 注意: 如果实现函数的功能需要对象属性,那么这个函数必须定义成对象方法,并且在方法中通过self来提供你所需要的对象属性
class Circle:
pi = 3.1415926
def __init__(self, r=5):
self.r = r
def area(self):
return Circle.pi * 3 ** 2
c1 = Circle(5)
print(c1.area())
05 继承
让子类直接拥有父类的属性和方法
语法:
class 类名(父类1, 父类2,...):
说明文档
类的内容
- 注意:如果定义类的时候没有写继承关系,那么这个类默认继承object(基类);(class 类名: == class 类名(object)😃
1)在子类中添加类属性和方法的时候,直接定义新的类属性和新的方法
2) 如果要在子类中添加对象属性,必须在子类的__init__
方法中通过super()
中调用父类的__init__
方法
class A:
a = 100
def __init__(self):
self.b = 200
self.c = 300
def func1(self):
print('A的对象方法')
@classmethod
def func2(cls):
print('A的类方法')
@staticmethod
def func3():
print('A的静态方法')
class B(A):
# 1)在子类中添加类属性和方法的时候,直接定义新的类属性和新的方法
m = 99
def func11(self):
print('B的对象方法')
@classmethod
def func22(cls):
print('B的类方法')
@staticmethod
def func33():
print('B的静态方法')
# 2) 如果要在子类中添加对象属性,必须在子类的__init__方法中通过super()中调用父类的__init__方法
def __init__(self):
super().__init__() # 调用当前类的父类的__init__方法
self.e = 400
self.f = 500
print(B.a)
x = B()
print(x.b, x.c)
x.func1()
B.func2()
B.func3()
print(B.m)
x.func11()
B.func22()
B.func33()