Python 各进制的表示与转换
Python 用 ob
表示二进制
二进制转十进制
>>> 0b10
2
>>> 0b11
3
用 0o
表示八进制
八进制转十进制
>>> 0o10
8
>>> 0o11
9
用 0x
表示十六进制
十六进制转十进制
>>> 0x10
16
>>> 0x1F
31
其他进制转二进制使用 bin()
函数
>>> bin(10)
'0b1010'
>>> bin(0o7)
'0b111'
>>> bin(0xE)
'0b1110'
其他进制转十进制使用 int()
函数
>>> int(0b111)
7
>>> int(0o77)
63
>>> int(0xE)
14
其他进制转十六进制使用 hex
函数
>>> hex(888)
'0x378'
>>> hex(0o7777)
'0xfff'
>>> hex(0b111)
'0x7'
其他进制转八进制使用 oct()
函数
>>> oct(0b111)
'0o7'
>>> oct(888)
'0o1570'
>>> oct(0x777)
'0o3567'
基本数据类型
- number
- int
- float
- bool
- Ture
- Flase
- 序列 有序,可以索引取值,切片,常用操作:
+
,*
,in
,not in
,len
,max
,min
- str 不可变
- list 可变
- tuple 不可变
- Set 集合 无序,可变,可以
-
求差集,&
求交集,|
求并集 - Dict 字典,无序,可变
number
>>> type(1*1)
>>> type(1*1.0)
>>> type(2/2)
>>> type(2//2)
>>> type(True)
>>> type(False)
>>> int(True)
1
>>> int(False)
0
>>> bool(1)
True
>>> bool(0)
False
>>> bool('abc')
True
>>> bool('')
False
>>> bool([1,2,3])
True
>>> bool([])
False
>>> bool(None)
False
字符串 str
原始字符串
在字符串前面加 r
表示原始字符串,即所见即所得
>>> print(r'hello /n world')
hello /n world
字符串运算
字符串拼接
>>> 'hello' + 'world'
'helloworld'
>>>
>>> 'hello' * 3
'hellohellohello'
索引
>>> 'hello world'[0]
'h'
>>> 'hello world'[1]
'e'
>>> 'hello world'[4]
'o'
>>> 'hello world'[-1]
'd'
>>> 'hello world'[-3]
'r'
切片
>>> 'hello world'[0:4]
'hell'
>>> 'hello world'[0:5]
'hello'
>>> 'hello world'[0:-1]
'hello worl'
>>> 'hello world'[6:10]
'worl'
>>> 'hello world'[6:11]
'world'
>>> 'hello world'[6:-1]
'worl'
>>> 'hello world'[6:]
'world'
>>> 'hello world'[-5:]
'world'
列表 list
定义列表
>>> ['hello', 1,2,3, True]
['hello', 1, 2, 3, True]
嵌套列表
>>> [['hello', 'world'], [1, 2], [True, False]]
[['hello', 'world'], [1, 2], [True, False]]
列表的基本操作
索引
>>> [1, 2, 3, 4][0]
1
>>> [1, 2, 3, 4][2]
3
切片,返回的是列表
>>> [1, 2, 3, 4][0:2]
[1, 2]
>>> [1, 2, 3, 4][-1:]
[4]
拼接
>>> [1, 2, 3, 4] + ['a', 'b']
[1, 2, 3, 4, 'a', 'b']
>>> [1, 2, 3, 4, 'a', 'b'] * 2
[1, 2, 3, 4, 'a', 'b', 1, 2, 3, 4, 'a', 'b']
元组 tuple
定义元祖
>>> (-1, 'hello', True)
(-1, 'hello', True)
元祖的基本操作
>>> (1, 2, 3)[0]
1
>>> (1, 2, 3)[-2:]
(2, 3)
>>> (1, 2) + ('a', 'b')
(1, 2, 'a', 'b')
>>> (1, 'a') * 2
(1, 'a', 1, 'a')
当 ()
中只有一个元素的时候,python 会默认把 ()
当做运算符,像是:(1 + 1) * 2
中的 ()
>>> type((1, 2, 3))
>>> type((1))
>>> type(('hello'))
如果想要定义只有一个元素的元组,可以在元素后面加一个英文逗号
>>> type((1,))
定义空元组
>>> type(())
已经有了列表,为什么需要元组?
为了代码稳定性。不可改变的元组类型有它的优势,因为当尝试修改元组的时候,会报错,避免错误隐藏在代码中。所以,列表和元组,优先选择使用元组,前提是存储的数据是静态的,不需要改变,如果存储的数据是动态的,需要改变,那么还是要用列表。
集合 set
定义集合
>>> {1, 2, 3, 'hello'}
{1, 2, 3, 'hello'}
序列有序,集合无序,所以集合无法索引取值
>>> {1, 2, 3}[0]
:1: SyntaxWarning: 'set' object is not subscriptable; perhaps you missed a comma?
Traceback (most recent call last):
File "", line 1, in
TypeError: 'set' object is not subscriptable
序列有序,集合无序,所以集合无法切片
>>> {1, 2, 3}[-2:]
:1: SyntaxWarning: 'set' object is not subscriptable; perhaps you missed a comma?
Traceback (most recent call last):
File "", line 1, in
TypeError: 'set' object is not subscriptable
集合的元素不能重复
>>> {1, 1, 2, 2, 3, 3}
{1, 2, 3}
集合的基本操作
>>> len({1, 2, 3})
3
>>> 2 in {1, 2, 3}
True
>>> 2 not in {1, 2, 3}
False
>>> {1, 2, 3, 4, 5, 6} - {3, 4}
{1, 2, 5, 6}
>>> {1, 2, 3, 4, 5, 6} & {3, 4, 7}
{3, 4}
>>> {1, 2, 3, 4, 5, 6} | {3, 4, 7}
{1, 2, 3, 4, 5, 6, 7}
定义一个空集合
>>> type({})
>>> type(set())
字典 dict
定义字典
>>> {1:'a', 2:'b', 3:'c'}
{1: 'a', 2: 'b', 3: 'c'}
Key 不能重复
>>> {1:'a', 1:'b', 3:'c'}
{1: 'b', 3: 'c'}
Key 不可变
>>> {[1,2]:'a', 1:'b', 3:'c'}
Traceback (most recent call last):
File "", line 1, in
TypeError: unhashable type: 'list'
>>> {(1,2):'a', 1:'b', 3:'c'}
{(1, 2): 'a', 1: 'b', 3: 'c'}
变量与运算符
值类型和引用类型
>>> a = 1
>>> b = a
>>> a = 3
>>> print(a)
3
>>> print(b)
1
>>> a = [1, 2, 3]
>>> b = a
>>> a[0] = 'x'
>>> print(a)
['x', 2, 3]
>>> print(b)
['x', 2, 3]
int
属于值类型,不可变;list
属于引用类型,可变。由于 int
不可改变,所以当 a = 3
给 a
进行重新赋值的时候,a
指向了一个新的值;当 a[0] = ['x']
修改了原来的值,a
不需要指向一个新的值,因为 list
是可变的。
值类型包括:int
str
tuple
引用类型包括:list
set
dict
不可变的字符串:
>>> a = 'hello'
>>> a[0]
'h'
>>> a[0] = 'x'
Traceback (most recent call last):
File "", line 1, in
TypeError: 'str' object does not support item assignment
可变的列表:
>>> a = [1, 2, 3]
>>> id(a)
140608652166656
>>> a[0] = 'x'
>>> print(a)
['x', 2, 3]
>>> id(a)
140608652166656
不可变的元组
>>> a = (1, 2, 3)
>>> a[0]
1
>>> a[0] = 'x'
Traceback (most recent call last):
File "", line 1, in
TypeError: 'tuple' object does not support item assignment
列表和元组
>>> l = [1, 2, 3]
>>> l.append(4)
>>> print(l)
[1, 2, 3, 4]
>>> t = (1, 2, 3)
>>> t.append(4)
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'tuple' object has no attribute 'append'
元组适合存储一组不变的数据;列表适合存储一组动态的数据。
元组中嵌套的列表是可以改变的
>>> t = (1, 2, [1, 2, 3])
>>> t[2][0] = 'x'
>>> print(t)
(1, 2, ['x', 2, 3])
运算符号
算数运算符:+
-
*
/
//
%
**
赋值运算符:=
+=
-=
*=
/=
%=
**=
//=
比较(关系)运算符:==
!=
>
<
>=
<=
逻辑运算符:and
or
not
成员运算符:in
not in
身份运算符:is
is not
位运算符:&
|
~
<<
>>
>>> a = 1
>>> a += a >= 1 # 相当于 a += True 所以等于是计算 a += 1
>>> print(a)
2
int
和 float
类型,非 0 时被 python 认为是 True
str
list
tuple
set
dict
类型,为空时被 python 认为是 False
>>> 1 and 1
1
>>> [1] or []
[1]
>>> not 1
False
根据两个元素判断真假,第一个元素能判断出来就直接返回第一个元素,第一个元素判断不出来就返回第二个元素
>>> 1 and 0 # 都为真结果才为真,1 为真,判断不出结果,0 为假,结果为假,返回 0
0
>>> 0 and 1 # 0 为假,可以判断结果为假,不需要判断第二个元素,直接返回 0
0
>>> 1 and 2
2
>>> 2 and 1
1
>>> 1 or 0 # 有一个为真,结果就为真,1 为真直接返回 1
1
>>> 0 or 1 # 0 为假,判断不出结果,再判断 1,1 为真,结果为真,返回 1
1
字典根据 key
判断 in
或者 not in
>>> 'a' in {'a': 1}
True
==
判断值是否相等,is
判断内存地址 id
是否相等
>>> a = 1
>>> b = 1.0
>>> id(a)
140519935187248
>>> id(b)
140519935914512
>>> a == b
True
>>> a is b
False
集合无序,元组有序
>>> s1 = {1, 2, 3}
>>> s2 = {3, 2, 1}
>>> s1 == s2
True
>>> s1 is s2
False
>>> t1 = (1, 2, 3)
>>> t2 = (3, 2, 1)
>>> t1 == t2
False
>>> t1 is t2
False
判断变量的类型
>>> a = 'hello'
>>> isinstance(a, str)
True
>>> isinstance(a, int)
False
>>> isinstance(a, (str, int, float))
True
>>> isinstance(a, (int, float))
False
对象的三个特征:value
id
type
,判断三个特征:==
is
isinstance
条件与循环
条件
account = 'answer'
password = '123456'
print('please input account:')
user_account = input()
print('please input password:')
user_password = input()
if account == user_account and password == user_password:
print('success')
else:
print('fail')
a = input()
a = int(a)
if a == 1:
print('apple')
elif a == 2:
print('orange')
elif a == 3:
print('banana')
else:
print('shopping')
循环
counter = 0
while counter <= 10:
counter += 1
print(counter)
else:
print('EOF')
a = [['apple', 'orange', 'banana'], (1, 2, 3)]
for x in a:
for y in x:
print(y)
else:
print('fruit is gone')
退出所有循环
a = [1, 2, 3]
for x in a:
if x == 2:
break
print(x)
1
退出本次循环
a = [1, 2, 3]
for x in a:
if x == 2:
continue
print(x)
1
3
# 实现 1,3,5,7
a = [1, 2, 3, 4, 5, 6, 7, 8]
# 循环实现
for i in range(0, len(a), 2):
print(a[i], end='|')
# 切片实现
b = a[0: len(a): 2]
print(b)
包、模块、函数与变量作用域
python 的组织结构:包->模块(.py文件)->类
当一个包被导入的时候,包中的 __init__.py
文件会自动执行
当导入一个模块的时候,就会执行这个模块的代码
c1.py
a = 2
print(a)
c2.py
import c1
执行 c2.py
python c2.py
执行结果
2
dir()
函数返回当前模块的所有变量,包括以双下划线 __
开头结尾的模块内置变量和我们自己定义的变量
模块内置变量:
__package__
返回包名,如果是入口文件,返回NoneType
因为入口文件不属于任何包__name__
返回包名.模块名
,如果是入口文件,返回__main__
__file__
返回模块在系统中的完整路径,如果是入口文件,返回模块名执行文件时的路径,比如执行python t/c2.py
,那么返回t/c2.py
__doc__
返回模块的文档注释
dir()
函数传入参数,返回指定模块的变量,比如 dir(sys)
-m
把入口文件当做模块执行,比如:python -m t.c2
相对导入和绝对导入
入口文件中不能使用相对导入,除非把入口文件当做模块执行
函数
认识函数
# 使用内置函数 round 保留小数点后两位
a = 3.14159
result = round(a, 2)
print(result)
函数的特点
- 功能性
- 隐藏细节
- 避免编写重复的代码
函数的定义及运行特点
def funcname(parameter_list):
pass
- 参数列表可以没有
- return 返回结果,没有 return 则返回 None
def add(x, y):
result = x + y
return result
def print_code(code):
print(code)
a = add(1, 2)
b = print_code('python')
print(a, b)
执行结果
python
(3, None)
如何让函数返回多个结果
def damage(skill1, skill2):
damage1 = skill1 * 2
damage2 = skill2 * 3 + 1
# 将返回一个元组
return damage1, damage2
# 使用有意义的变量名接收返回结果
skill1_damage, skill2_damage = damage(3, 2)
print(skill1_damage, skill2_damage)
序列解包
d = 1,2,3
# d 的类型是元组
print(type(d))
# 序列解包
a,b,c = d
关键字参数
def damage(skill1, skill2):
damage1 = skill1 * 2
damage2 = skill2 * 3 + 1
return damage1, damage2
# 调用函数的时候,实参使用关键字参数,代码更易读
skill1_damage, skill2_damage = damage(skill1=3, skill2=2)
可变参数
任意个数的参数
def demo(*param):
print(type(param))
print(param)
demo(1,2,3)
执行结果
(1, 2, 3)
使用可变参数
def sum(*param):
sum = 0
for i in param:
sum += i
print(sum)
sum(1,2,3)
执行结果
6
关键字可变参数
任意个数的关键字参数
def city_temp(**param):
print(type(param))
print(param)
city_temp(bj='32c', sh='36c', gz='38c')
执行结果
{'sh': '36c', 'gz': '38c', 'bj': '32c'}
使用
def city_temp(**param):
for key,value in param.items():
print(key, ':', value)
d = {'bj':'32c', 'sh':'36c', 'gz':'38c'}
# 如果实参是字典,加两个**
city_temp(**d)
变量作用域
每一个变量,都有它的作用范围
c = 10
def add(x, y):
c = x + y
print(c)
add(1, 2)
print(c)
执行结果
3
10
再看一个例子,在函数内部定义一个变量,然后在函数外部打印这个变量
def demo():
a = 1
print(a)
在函数外部打印变量 a ,执行结果,报错
NameError: name 'a' is not defined
如果先定义一个变量,然后在函数内部引用变量,再执行函数是可以的
a = 1
def demo():
print(a)
demo()
执行结果
1
在函数外部定义的变量,被称为全局变量;在函数内部定义的变量,被称为局部变量。
然后看一下,在循环外部,是可以引用循环内部定义的变量的
def demo():
for i in range(0,3):
a = 1
print(a)
demo()
执行结果
1
作用域链
引用变量时,由内到外逐级寻找
a = 1
def func1():
a = 2
def func2():
a = 3
print(a)
func2()
func1()
执行结果
3
注释掉 a = 3
a = 1
def func1():
a = 2
def func2():
# a = 3
print(a)
func2()
func1()
执行结果
2
再注释掉 a = 2
a = 1
def func1():
# a = 2
def func2():
# a = 3
print(a)
func2()
func1()
执行结果
1
global 关键字
把局部变量变成全局变量
def demo():
global a
a = 1
demo()
print(a)
执行结果
1
全局变量不会局限在当前模块,比如此时的变量 a ,是全局变量,那么在其他模块也是可以引用的。
面向对象
类的定义
变量名小写,单词之间使用下划线间隔
类名首字母大写,单词之间使用大写字母间隔,而不是使用下划线间隔
类下面的函数,必须有 self
参数
在函数中引用类下面的全局变量的时候,也必须加 self.
参数
class Student():
name = '张三'
age = 18
def print_file(self):
print('name: ' + self.name)
print('age: ' + str(self.age))
使用类之前,需要先对类进行实例化
student = Student()
调用类下面的函数
student.print_file()
执行结果
name: 张三
age: 18
类最基本的作用,就是像上面这样,把变量和函数封装起来
一个模块下面可以定义多个类
定义类的模块下面只定义类,类的实例化和使用放在其他模块下面
函数与方法的区别
直接定义在模块下面的函数,称为函数;定义在类下面的函数,称为方法
直接定义在模块下面的变量,称为变量,定义在类下面的变量,称为数据成员
不必纠结函数/方法的叫法。
类与对象
类是现实世界或思维世界中的实体在计算机中的反映。它将数据(变量)以及对这些数据的操作(方法)封装在一起。
变量(数据成员)是类或对象的特征,方法是类或对象的行为。
类像模板,通过这个模板可以产生很多个不同的对象。
构造函数
类在实例化的时候,会自动调用构造函数 __init__()
构造函数除了在类实例化的时候,自动调用,也可以显示的调用,但很少这样做。
函数在没有做 return
的时候,会默认返回 None
,构造函数也一样。
构造函数可以显示的 return None
,但是不能 return
其他内容。
类变量与实例变量
类变量是和类相关的变量;实例变量是和对象相关的变量。
局部变量不会覆盖全局变量;实例变量不会覆盖类变量。
通过构造函数创建类这个模板的不同对象(实例化)
class Student():
# 类变量
name = '张三'
age = 18
# 构造函数,初始化对象的属性
def __init__(self, name, age):
# 实例变量
self.name = name
self.age = age
def do_homework(self):
print('homework')
# 实例化
student1 = Student('小明', 18)
student2 = Student('李雷', 20)
# 实例变量
print(student1.name)
print(student2.name)
# 类变量
print(Student.name)
执行结果
小明
李雷
张三
类变量定义 name 和 age 其实不合适,因为类是抽象的,不能说学生们的名字和年龄是什么,应该定义为实例变量,因为实例是具体的,可以说某个学生的姓名和年龄是什么。那类变量怎么用呢?
比如,可以创建一个类变量,用来计算一个班级的学生总人数
class Student():
# 类变量,一个班级的学生总数
sum = 0
# 构造函数,初始化对象的属性
def __init__(self, name, age):
# 实例变量
self.name = name
self.age = age
类与对象的变量查找顺序
当访问一个实例变量的时候(student1.name
),首先会在实例的所有变量中查找(student1.__dict__
),如果没有找到,会在类变量里面查找(Student.__dict__
),如果还没有的话,会到父类中查找。
self 与实例方法
实例方法:与实例相关的方法,第一个参数是 self
class Student():
sum = 0
# 构造函数
def __init__(self, name, age):
self.name = name
self.age = age
# 实例方法
def do_homework(self):
print('homework')
self
就是当前对象,比如对象 student1
调用 do_homework()
方法(student1.do_homework()
),那么这时候 do_homework(self)
方法中的 self
参数,就是指的对象 student1
构造函数属于特殊的实例方法,与普通的实例方法有所不同:
- 首先,调用方式不同
- 调用构造函数:
Student('小明', 18)
- 调用普通实例方法:
student1.do_homework()
- 调用构造函数:
- 其次,作用不同
- 构造函数用来初始化对象的属性
- 普通实例方法用来定义对象的行为
在实例方法中访问实例变量与类变量
在实例方法中访问实例变量和类变量
class Student():
# 类变量
sum = 0
# 构造函数
def __init__(self, name, age):
# 实例变量
self.name = name
self.age = age
# 在实例方法中访问实例变量
print(self.name)
# 在实例方法中访问类变量的第一种方式
print(Student.sum)
# 在实例方法中访问类变量的第二种方式
print(self.__class__.sum)
实例化类,自动调用构造函数
student1 = Student('小明', 18)
执行结果
小明
0
0
在实例方法中,修改类变量
class Student():
# 类变量
sum = 0
# 构造函数
def __init__(self, name, age):
# 实例变量
self.name = name
self.age = age
# 修改类变量
Student.sum += 1
print('当前班级学生总数是:' + str(Student.sum))
每实例化一次,就自动调用一次构造函数
student1 = Student('小明', 18)
student2 = Student('李雷', 20)
student3 = Student('小红', 17)
执行结果
当前班级学生总数是:1
当前班级学生总数是:2
当前班级学生总数是:3
类方法
类方法用于操作类相关的变量
定义类方法
- 在方法上添加
@classmethod
- 第一个参数
cls
class Student():
# 类变量
sum = 0
# 构造函数
def __init__(self, name, age):
# 实例变量
self.name = name
self.age = age
# 实例方法
def do_homework(self):
print('homework')
# 类方法
@classmethod
def plus_sum(cls):
cls.sum += 1
print('当前班级学生总数是:' + str(cls.sum))
每创建一个对象之后,调用一次类方法
student1 = Student('小明', 18)
Student.plus_sum()
student2 = Student('李雷', 20)
Student.plus_sum()
student3 = Student('小红', 17)
Student.plus_sum()
执行结果
当前班级学生总数是:1
当前班级学生总数是:2
当前班级学生总数是:3
对象也可以调用类方法,但是不建议这么用
cls
就是当前类。Student.plus_sum()
时,plus_sum(cls)
中的 cls
就指的是类 Student
类方法不能访问实例变量
静态方法
静态方法需要在方法名上添加 @staticmethod
静态方法没有 self
或 cls
参数
静态方法可以被对象,也可以被类调用
静态方法不能访问实例变量
静态方法,不建议用
成员可见性:公开和私有
成员:指的是变量和方法
变量和方法的调用,都有内部调用和外部调用
class Student():
sum = 0
def __init__(self, name, age):
self.name = name
self.age = age
def do_homework(self):
# 内部调用
self.do_english_homework()
print('homework')
def do_english_homework(self):
print('english homework')
student1 = Student('小明', 18)
# 外部调用
student1.do_english_homework()
有时候我们不希望变量在外部被修改,比如下面的实例变量 score
class Student():
sum = 0
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
不希望像这样在外部被修改
student1 = Student('小明', 18)
student1.score = -2
所以,可以添加一个方法,专门用于操作 score
class Student():
sum = 0
def __init__(self, name, age):
self.name = name
self.age = age
# 初始化默认为 0
self.score = 0
def marking(self, score):
# 判断如果传入的分数小于 0
if score < 0:
# 那么分数等于 0
score = 0
# 如果传入的分数不小于 0,那么分数就等于传入的分数
self.score = score
print(self.name + '同学的考试分数是:' + str(self.score))
student1 = Student('小明', 18)
student1.marking(-1)
student1.marking(59)
结果
小明同学的考试分数是:0
小明同学的考试分数是:59
所有对类下面的变量进行修改的操作,都应该由方法来完成。
但是,现在其实仍然可以通过 student1.score = -3
在外部直接赋值,因为 score
的成员可见性是公开的。
在 python 中,如果变量或方法没有以双下划线开头(只开头,不结尾),那么它的可见性就是公开的。
所以可以把 score
变成私有变量
class Student():
sum = 0
def __init__(self, name, age):
self.name = name
self.age = age
# 私有变量
self.__score = 0
def marking(self, score):
# 判断如果传入的分数小于 0
if score < 0:
score = 0
# 如果传入的分数不小于 0
self.__score = score
print(self.name + '同学的考试分数是:' + str(self.__score))
然后在外部赋值
student1 = Student('小明', 18)
student1.__score = -1
结果:没有报错
查看对象的成员
print(student1.__dict__)
结果
{'name': '小明', 'age': 18, '_Student__score': 0, '__score': -1}
结果中值等于 0 的 _Student__score
是私有变量 __scoore
,而值等于 -1 的 __score
是在外部赋值的时候,给对象添加了一个新的变量。python 会对私有变量重新命名,以这种方式达到私有变量再被外部调用的时候不被找到,不过其实可以通过 _Student__score
来访问,所以严格的说,python 没有私有变量。
继承
继承,避免我们定义重复的变量或重复的方法。
父类
class Human:
sum = 0
def __init__(self, name, age):
self.name = name
self.age = age
def get_name(self):
print(self.name)
子类继承父类
class Student(Human):
def __init__(self, name, age):
self.name = name
self.age = age
def do_homework(self):
print('homework')
执行
student1 = Student('小明', 18)
print(Student.sum)
print(student1.sum)
print(student1.name)
print(student1.age)
student1.get_name()
结果
0
0
小明
18
小明
在子类中,调用父类的方法
class Student(Human):
def __init__(self, school, name, age):
self.school = school
# 调用父类的构造函数
Human.__init__(self, name, age)
def do_homework(self):
print('homework')
执行
student1 = Student('清华大学', '小明', 18)
print(student1.school)
print(student1.name)
print(student1.age)
结果
清华大学
小明
18
上面这样在子类的中调用父类的方法的方式,虽然可以,但是有问题,Human.__init__(self, name, age)
是在用类,调用实例方法
所以,调用父类的方法需要使用 super()
函数:
super(当前类名, self).要调用的父类当中的方法名(参数)
父类
class Human:
sum = 0
def __init__(self, name, age):
self.name = name
self.age = age
def get_name(self):
print(self.name)
def do_homework(self):
print('这是父类中的 do_homework 方法')
子类
class Student(Human):
def __init__(self, school, name, age):
self.school = school
# 调用父类的构造函数
super(Student, self).__init__(name, age)
def do_homework(self):
# 调用父类中的 do_homework 方法
super(Student, self).do_homework()
print('这是子类中的 do_homework 方法')
执行
student1 = Student('清华大学', '小明', 18)
student1.do_homework()
结果
这是父类中的 do_homework 方法
这是子类中的 do_homework 方法