面向对象
1.方法
1)对象方法
怎么定义:直接定义在类中的函数
怎么调用:通过对象调用
特点:有默认参数self,self在调用的时候不用传参,系统自动将当前对象传给self
什么时候用:如果实现函数的功能需要对象属性就使用对象方法(对象方法中的self可以用来提供需要所有的对象属性)
2)类方法
怎么定义:在类中定义函数前加装饰器@classmethod
怎么调用:通过类调用
特点:自带参数cls,cls在调用的时候也不需要传参,系统会自动将当前类传给cls(谁调用就指向谁)
什么时候用:实现函数功能在不需要对象属性的时候需要类,就使用类方法
3)静态方法
怎么定义:在类型定义函数前加装饰器@staticmethod
怎么调用:通过类调用
特点:没有默认参数
什么时候用:实现函数功能既不需要类也不需要对象属性就使用静态方法
对象方法 | 类方法 | 静态方法 | |
---|---|---|---|
怎么定义 | 直接定义在类中的函数 | 在类中定义函数前加装饰器@classmethod | 在类型定义函数前加装饰器@staticmethod |
怎么调用 | 通过对象调用 | 通过类调用 | 通过类调用 |
特点 | 有默认参数self,self在调用的时候不用传参,系统自动将当前对象传给self | 自带参数cls,cls在调用的时候也不需要传参,系统会自动将当前类传给cls(谁调用就指向谁) | 没有默认参数 |
什么时候用 | 如果实现函数的功能需要对象属性就使用对象方法(对象方法中的self可以用来提供需要所有的对象属性) | 实现函数功能在不需要对象属性的时候需要类,就使用类方法 | 实现函数功能既不需要类也不需要对象属性就使用静态方法 |
class A:
# fun1是对象方法
def fun1(self):
print('对象方法', self)
@classmethod
def fun2(cls):
print('类方法', cls)
@classmethod
def fun3(cls, x):
print(x)
@staticmethod
def fun4():
print('静态方法')
print(A) # <class '__main__.A'>
A.fun2() # 类方法 <class '__main__.A'>
A.fun3(1) # 1
A.fun4() # 静态方法
- 方法在定义的时候的参数问题:看实现函数的功能除了类中属性以外需不需要额外的数据,需要几个
class Person: def __init__(self, name): self.name = name def eat(self, food): print(f'{self.name}今天吃了{food}')
- 方法的调用问题:本质上,不管什么方法都可以用对象和类调用
a = A() a.fun1() # A.fun1(100) # 注意:类可以调用对象方法,但是self就必须自己传参,失去可以指向当前对象的意义 A.fun2() print('====') a.fun2() # 注意:对象可以调用类方法,调用的时候cls还是指向当前类,但是会消耗额外的cpu资源和内存资源
2.对象属性的增删改查
class Person:
def __init__(self, name, tel, age=18, gender='男'):
self.name = name
self.age = age
self.tel = tel
self.gender = gender
# __repr__会在当前类的对象被打印的时候自动调用,并且打印结果就是这个函数的返回值。(返回值必须是字符串)
def __repr__(self):
# return str(self.__dict__)
return f'<{str(self.__dict__)[1:-1]}>'
p1 = Person('小明', '110')
p2 = Person('小红', '120', 20, '女')
print(p1) # print(p1) == print(p1.__repr__())
print(p2) # <'name': '小红', 'age': 20, 'tel': '120', 'gender': '女'>
# print(p1.__dict__)
- 查(获取对象属性的值)
- 对象.属性
- getattr(对象,属性名) / getattr(对象,属性名,默认值)
print(p1.name) print(getattr(p1, 'name')) # value = input('请输入属性名:') # print(getattr(p1, value)) value = 'name' # print(p1.value) # 报错 print(getattr(p1, value)) # print(p1.height) # AttributeError: 'Person' object has no attribute 'height' print(getattr(p1, 'height', 170)) # 170
- 增、改
- 对象.属性 = 值
- setattr(对象, 属性名, 值)
print('修改前:', p1) # 修改前: <'name': '小明', 'age': 18, 'tel': '110', 'gender': '男'> p1.age = 20 print('修改后:', p1) # 修改后: <'name': '小明', 'age': 20, 'tel': '110', 'gender': '男'> p1.weight = 60 print('增加后:', p1) # 增加后: <'name': '小明', 'age': 20, 'tel': '110', 'gender': '男', 'weight': 60> setattr(p1, 'height', 170) print(p1) # <'name': '小明', 'age': 20, 'tel': '110', 'gender': '男', 'weight': 60, 'height': 170>
- 删
- del 对象.属性
- delattr(对象, 属性名)
del p1.gender print(p1) # <'name': '小明', 'age': 20, 'tel': '110', 'weight': 60, 'height': 170> delattr(p1, 'weight') print(p1) # <'name': '小明', 'age': 20, 'tel': '110', 'height': 170>
3.内置类的属性
class Dog:
"""狗类"""
num = 100
def __init__(self, name, age=3, color='黄色', gender='公'):
self.name = name
self.gender = gender
self.age = age
self.color = color
def show_message(self):
print(self.name, self.gender, self.color)
@classmethod
def show_num(cls):
print('狗的数量', cls.num)
@staticmethod
def info():
print('狗是人类的朋友!')
dog = Dog('小花')
- _ _ doc _ _ - 获取类的说明文档
print(Dog.__doc__) print(int.__doc__)
- _ _ class _ _ - 获取对象的类型(对象属性),功能和type()函数一样
print(dog.__class__) # <class '__main__.Dog'> print(type(dog)) # <class '__main__.Dog'>
- _ _ name _ _ - 获取类名(类属性)
- _ _ module _ _ - 获取类所在的模块的模块名(类属性)
-
_ _ dict _ _ - 获取指定类所有的类属性及其对应的值(以字典的形式返回) (了解)
_ _ dict _ _ - 获取指定对象所有的对象属性及其对应的值
print(Dog.__dict__)
print(dog.__dict__) # {'name': '小花', 'gender': '公', 'age': 3, 'color': '黄色'}
-
_ _ base _ _ - 获取指定类的父类
_ _ bases _ _ - 获取指定类的父类们
4.运算符重载
-
Python中的运算符
Python中每一个运算符都对应一个固定的魔法方法,每次使用运算符的时候本质就是去调用对应方法。
某种类型的数据是否支持某种运算符和这个类型中有没有实现运算符对应的魔法方法有关
- 在自己的类中重载指定运算符
class Student: def __init__(self, name, age=18, score=0): self.name = name self.age = age self.score = score def __repr__(self): return f'<{str(self.__dict__)[1:-1]}>' # ===========运算符重载======== def __lt__(self, other): return self.score > other.score # self是+前面的数据,other是+后面的数据,返回值是计算结果 def __add__(self, other): return self.score + other.score stu1 = Student('小明', age=35, score=90) stu2 = Student('小红', age=20, score=80) stu3 = Student('汤姆', age=31, score=89) print(stu1 != stu2) # 默认支持比较相等 print(stu1 + stu2) # 相当于 stu1.__add__(stu2) print(stu1) # <'name': '小明', 'age': 35, 'score': 90> print(stu1 > stu2) # True # 将学生成绩从大到小排序 students = [stu1, stu2, stu3] print(sorted(students, key=lambda element:element.score, reverse=True)) students.sort() print(students)