类
基础
class Student():
SCHOOL = 'No. 1 Middle School' # 类的常量
def __init__(self, name, age, ID): # 所有函数都要有形参 self: 一个指向实例的引用
self.name = name
self.age = age
self.profession = 'student' # 属性默认值(区别参数默认值)
self.__ID = ID # 私有属性
# 类函数
@classmethod
def create_student(cls, name): # cls为类
return cls(name = name, age=18, ID=None) # 传到__init__构造函数
# 静态函数
@staticmethod
def out_text(text):
print(text)
# 成员函数
def update_age(self, age):
self.age = age
stu = Student("Amy", 18, 1001)
print(Student.SCHOOL, stu.SCHOOL)
print(stu.name) # Amy
print(stu.profession) # student
print(stu.__ID) # 报错,私有属性不可访问
stu2 = Student.create_student('Bob')
stu2.out_text('nothing.')
属性
- .__xxx 为私有属性,实例对象中不可访问和修改
- .xxx 为普通属性
函数
- __init__() 为构造函数: 类中必有,当创建类的实例时,python首先自动调用它。
- 类函数:实现不同的 init 构造函数,访问或者修改对象的属性,第一个参数为 cls,可用装饰器
@classmethod
。 - 静态函数:做简单独立的任务,与类没有什么关联,没有形参 self。可用装饰器
@staticmethod
。 - 成员函数:访问或者修改对象的属性
类中常用装饰器
@staticmethod
@classmethod
@property
继承
基础
class Student():
"""父类:学生"""
def __init__(self, name, age):
self.name = name
self.age = age
self.professional = 'student'
def study(self):
raise Exception('study() not implemented') # 阻止调用父类,必须重写
def print_name(self):
print(self.name)
class Hobby:
"""父类:爱好"""
def __init__(self, hobby_name="reading"):
self.hobby_name = hobby_name
def print_hobby(self):
print(self.hobby_name)
class Girl(Student):
"""子类:女生"""
def __init__(self, name, age, hobby_name):
super().__init__(name, age) # 调用父类的__init__()
# Student.__init__(name, age)
self.sex = 'female'
self.hobby = Hobby(hobby_name) # 属性为某个类的实例
# 重写
def study(self):
print(f"A girl {self.name} is studying.")
g = Girl("Amy", 18, "dancing")
g.study()
g.print_name() # 调用父类的方法
g.hobby.print_hobby()
- 创建实例时,
若子类有__init__(),则python不会调用父类的__init__()
若子类没有,则调用父类的__init__() - 子类自动继承父类的属性和方法
- self.xxx
- super().xxx
- 重写、重载
重写覆盖,重载不覆盖
- 重写:子类的func()与父类的函数名和参数均相同,子类只有自己的func(),父类的被覆盖
- 重载:子类的func()与父类的函数名相同,参数不同,子类有父类的func()和自己的func()
- 继承:super() 或 子类的属性是某个类的实例
多重继承
class A():
def __init__(self):
print('enter A')
print('leave A')
class B(A):
def __init__(self):
print('enter B')
super().__init__()
print('leave B')
class C(A):
def __init__(self):
print('enter C')
super().__init__()
print('leave C')
class D(B, C):
def __init__(self):
print('enter D')
super().__init__()
print('leave D')
D() # 调用顺序:按层遍历,从左到右进入
"""
enter D
enter B
enter C
enter A
leave A
leave C
leave B
leave D
"""
抽象类、抽象函数
为了防止父类对象化(实例化),用抽象类。
定义接口:抽象类是一种自上而下的设计风范,你只需要用少量的代码描述清楚要做的事情,定义好接口,然后就可以交给不同开发人员去开发和对接。
class Student():
def study(self):
pass
class Girl(Student):
# 重写
def study(self):
print(f"A girl is studying.")
g = Girl()
g.study()
stu = Student() # 不报错
stu.study()
抽象类:它生下来就是作为父类存在的,一旦对象化就会报错。
抽象函数:定义在抽象类之中,子类必须重写该函数才能使用。
from abc import ABCMeta, abstractmethod
class Student(metaclass=ABCMeta): # 抽象类
@abstractmethod # 抽象函数
def study(self):
pass
class Girl(Student):
# 重写
def study(self):
print(f"A girl is studying.")
g = Girl()
g.study()
stu = Student() # 报错
stu.study()
面向对象 OPP
面向对象编程的四要素: 类、属性、函数(方法)、对象(实例)
三特征:封装、继承、多态
str 与 repr
都是将类的实例转换为字符串
当 str 和 repr 均有时:
class Student():
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return '(str, {}, {})'.format(self.name, self.age)
# return str(('repr', self.name, self.age))
def __repr__(self):
return repr(('repr', self.name, self.age))
# return '(repr, {}, {})'.format(self.name, self.age)
stu = Student('a', 20)
print(stu) # (str, a, 20)
print(str(stu)) # (str, a, 20)
print('{}'.format(stu)) # (str, a, 20)
print([stu]) # [('repr', 'a', 20)]
print(repr(stu)) # ('repr', 'a', 20)
li = [
Student('a', 20),
Student('b', 40)
]
print(li) # [('repr', 'a', 20), ('repr', 'b', 40)]
当只有 repr 时:
class Student():
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return repr(('repr', self.name, self.age))
stu = Student('a', 20)
print(stu) # ('repr', 'a', 20)
print(str(stu)) # ('repr', 'a', 20)
print('{}'.format(stu)) # ('repr', 'a', 20)
print([stu]) # [('repr', 'a', 20)]
print(repr(stu)) # ('repr', 'a', 20)
li = [
Student('a', 20),
Student('b', 40)
]
print(li) # [('repr', 'a', 20), ('repr', 'b', 40)]
当只有 str 时:
class Student():
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return '(str, {}, {})'.format(self.name, self.age)
stu = Student('a', 20)
print(stu) # (str, a, 20)
print(str(stu)) # (str, a, 20)
print('{}'.format(stu)) # (str, a, 20)
print([stu]) # [<__main__.Student object at 0x0000021B652F1B20>]
print(repr(stu)) # <__main__.Student object at 0x0000021B652F1B20>
li = [
Student('a', 20),
Student('b', 40)
]
print(li) # [<__main__.Student object at 0x0000021B652E4970>, <__main__.Student object at 0x0000021B652E40A0>]
调用时机 | str | repr |
---|---|---|
√(优先) | √ | |
字符串、tuple | √(优先) | √ |
列表 | × | √ |
repr | × | √ |
https://baijiahao.baidu.com/s?id=1596817611604972751&wfr=spider&for=pc