1.查 - 获取对象属性的值 对象.属性
getattr(对象, 属性名, 默认值) - 可以做到动态获取属性的值,并且可以赋默认值,如果属性名不存在,不会报错且返回默认值
print(stu1.name) print(getattr(stu1, 'name')) value = input('请输入要获取的属性的属性名:') print(getattr(stu1, value))2.增/改 对象.属性 = 值 属性存在就是改,属性不存在就是增加
setattr(对象, 属性名, 值)
stu1.name = '小轩' print(stu1) # {'name': '小轩', 'age': 18, 'study_id': '001', 'scores': 86} stu1.weight = 130 print(stu1) # {'name': '小轩', 'age': 18, 'study_id': '001', 'scores': 86, 'weight': 130} setattr(stu1, 'weight', 125) print(stu1) # {'name': '小轩', 'age': 18, 'study_id': '001', 'scores': 86, 'weight': 125}3.删 - 删除对象属性 del 对象.属性
delattr(对象, 属性名)
del stu1.study_id print(stu1) # {'name': '小轩', 'age': 18, 'scores': 86, 'weight': 125} delattr(stu1, 'weight') print(stu1) # {'name': '小轩', 'age': 18, 'scores': 86}对象方法 怎么定义:直接定义在类中的函数 怎么调用:通过 ‘对象.方法名’ 的形式来调用 特点:自带参数self,用对象调用方法的时候参数self不需要传参,系统会自动将当前对象传给self (self:谁调用就指向谁) 什么时候用:如果实现函数功能需要用到对象属性,那么这个函数就定义成对象方法
类方法 怎么定义:在定义前加装饰器@classmethod 怎么调用:类.方法名 特点:有个默认参数cls,这个参数在调用的时候不用传参,系统会自动将当前类传给cls 什么时候用:实现函数的功能在不需要对象属性的前提下需要类就使用类方法
静态方法 怎么定义:在定义前加装饰器@staticmethod 怎么调用:类.方法名() 特点:没有默认参数(相当于类中的普通函数) 什么时候用:实现函数的功能在不需要对象属性的前提下不需要类就使用静态方法
class Student: num = 100 def __init__(self, name='张三'): self.name = name def func1(self): # 对象方法 print(self.name) @classmethod def func2(cls): # cls:Student print(f'cls:{cls}') print('类方法', Student.num) @staticmethod def func3(): print('静态方法') print('Student:', Student) Student.func2() # 类方法 100 Student.func3() # 静态方法 s1 = Student() s1.func1() # 张三1.getter和setter
getter 什么时候用:在获取对象属性前,如果要对别的属性做什么事情,就可以给这个属性添加getter 怎么用: 第一步:在需要添加getter的属性的属性名前加_ 第二步:在装饰器@property后面定义一个函数:a.函数名就是属性名去掉下划线;b.函数没有参数,需要一个返回值(获取这个属性真正得到的结果) 第三步:通过对象去获取属性的时候,属性不需要带下划线
setter - 添加setter之前必须先添加getter 什么时候用:如果要在给某个对象属性赋值之前做别的什么事情,就给这个属性添加setter 怎么用: 第一步:在需要添加setter的属性的属性名前加_ 第二步:在装饰器@getter名.setter后面定义一个函数 函数名就是属性名去掉_,函数有一个参数(这个参数指向的是赋值的时候赋的值),没有返回值 第三步:通过对象给属性赋值的时候,属性不需要带下划线
# 练习:给Person添加属性age 要求:age中保存年龄值,获取age属性的时候得到的是这个年龄值对应的阶段状态: # 儿童(0~4)、少年(5~12)、青年(13~28)、壮年(29~40)、中年(41~55)、老年(55岁以上) class Person: def __init__(self, age=20): self._age = age @property def age(self): if 0 <= self._age <= 4: return '儿童' if 5 <= self._age <= 12: return '少年' if 13 <= self._age <= 28: return '青年' if 29 <= self._age <= 40: return '壮年' if 41 <= self._age <= 55: return '中年' if 55 < self._age < 100: return '老年' else: return '滚呀!' @age.setter def age(self, value): if type(value) != int: raise ValueError if value < 0 or value > 150: raise ValueError self._age = value p1 = Person(34) # 如果使用这个给对象赋值,不会进入setter函数 print(p1.age) # 壮年 p1.age = 170 # ValueError1.访问权限
三种访问权限 公开的:公开的属性和方法在类的内部和外部都可以用,并且可以被继承 保护的:保护的属性和方法在类的内部可以用,外部不能用,但是可以被继承 私有的:私有的属性和方法在类的内部可以用,外部不能用,而且不能被继承 python中的属性和方法只有一种访问权限:公开的,所谓的私有化其实是假的
私有化的方法 在属性名和方法前加__(只能是两个下划线开头,不能用两个下划线结尾)
class Person: num1 = 50 __info = '动物' @staticmethod def func1(): print(Person.__info) Person.func1() # print(Person.__info) # 报错 print(Person._Person__info)1.运算符 python在使用运算符的时候本质是在调用这个运算符对应的方法, 每个运算符都对应的方法的的方法名是固定的 不同类型的数据在参与相同的运算符的时候,会调用不同类中对应的方法
某个类型的数据是否支持某种运算,就看这个数据对应的类型中有没有实现这个运算符对应的方法
class Person: def __init__(self, name='小明', age=18, gender='男'): self.name = name self.age = age self.gender = gender def __lt__(self, other): return self.age < other.age def __repr__(self): return f'<{str(self.__dict__)[1:-1]}>' # 练习:将ps中的元素按照年龄的大小从小到大排序 p1 = Person() p2 = Person('小花', 28, '女') p3 = Person('张三', 20, '男') p4 = Person('老王', 25, '男') ps = [p1, p2, p3, p4] ps.sort() print(ps)