学习Python Day18 —— 面向对象编程(2)

本文深入探讨Python面向对象编程,包括对象属性的增删改查,对象方法、类方法和静态方法的定义及调用,以及getter和setter的使用。此外,还介绍了私有化和运算符重载的概念。
摘要由CSDN通过智能技术生成

学习Python Day18 —— 面向对象编程(2)

对象属性的增删改查

class Student:
    def __init__(self, name, tel, study_id="0001", score=0):
        self.name = name
        self.tel = tel
        self.study_id = study_id
        self.score = score

    # 在打印一个对象的时候,系统会自动用这个对象去调用__repr__方法,
    # 并且会获取这个方法的返回值,返回值是什么就打印什么(返回值必须是字符串)
    def __repr__(self):
        return f"<{str(self.__dict__)[1:-1]}>"

stu1 = Student("小明", "110", score=100)
stu2 = Student("隔壁老王", "120", "0002", 78)
print(stu1)
查 - 获取对象属性的值

对象.属性
getattr(对象, 属性名)

print(stu1.name)
print(getattr(stu1, "name"))
# 1)getattr可以做到动态获取属性的值
value = input("请输入需要获取的值:")
print(getattr(stu1, value))
print(getattr(stu1, "height", 180)) 
增/改

对象.属性 = 值
setattr(对象, 属性名, 值)

# 属性存在就是改
stu1.name = "小红"
setattr(stu1, "tel", "199")
print(stu1)

# 属性不存在就是增加
stu1.height = 175
setattr(stu1, "weight", 130)
print(stu1)

del 对象.属性
delattr(对象, 属性名)

del stu1.study_id
print(stu1)

delattr(stu1, "score")
print(stu1)
对象方法

怎么定义:直接定义
怎么调用:对象.方法名()
特点:有个默认参数self,这个参数在调用的时候不用传参,系统会自动将当前类传给self
什么时候用:如果实现函数的功能需要用到对象属性,那么这个函数就定义成对象方法

类方法

怎么定义:在定义函数前加装饰器@classmethod
怎么调用:类.方法名()
特点:有个默认参数cls,这个参数在调用的时候不用传参,系统会自动将当前类传给cls
什么时候用:如果实现函数的功能在不需要对象属性的前提下需要用到类属性,那么这个函数就定义成类方法

静态方法

怎么定义:在定义函数前加装饰器@staticmethod
怎么调用:类.方法名()
特点:没有默认参数(相当于类中的普通方法)
什么时候用:实现函数的功能不需要对象属性的前提下不需要类就使用静态方法

class Student:
    num = 100
    # fun1是对象方法
    def func1(self):
        pass

    @classmethod
    def func2(cls):
        print("类方法")
        # 当前类能做的cls都可以做
        stu1 = Student()
        stu2 = cls()
        print(stu1, stu2)

    @staticmethod
    def func3():
        print("静态方法")

Student.func2()
Student.func3()

内置类属性

class Person:
    """
    人类
    """
    num = 61

    def __init__(self, name="张三", age=18, gender="男"):
        self.name = name
        self.age = age
        self.gender = gender

    def eat(self, food="面条"):
        print(f"{self.name}在吃{food}")

    @classmethod
    def message(cls):
        print(f"人类现在的数量是{cls.num}")

    @staticmethod
    def destroy():
        print("人类破坏环境!")

p1 = Person()

# 1.类.__doc__     -  获取类的说明文档
print(Person.__doc__)

# 2.类.__module__    -  获取类所在的模块
print(list.__module__)

# 3.对象.__class__    -  获取指定对象对应的类型,和type(对象)功能一样
print(p1.__class__)     # <class '__main__.Person'>
print(type(p1))         # <class '__main__.Person'>
print(Person)           # <class '__main__.Person'>

# 4.类.__name__      -  获取类名
print(Person.__name__)      # Person
print(p1.__class__.__name__)    # Person

# 5.
# 类.__dict__    -  将类转换成字典,key是字段名,value是字段对应的值
# 对象.__dict__   -  将对象转换成字典,对象属性名作为key,属性值作为value
print(Person.__dict__)
print(p1.__dict__)

# 6.
# 类.__base__  -  获取指定类的父类
# 类.__bases__  -  获取指定类的父类
# object是python中所有类的基类
print(Person.__base__)      # <class 'object'>
print(Person.__base__.__name__)     # object

getter和setter

getter

a.什么时候用:在获取对象属性前,如果要做别的什么事情,就可以给这个属性添加getter
b.怎么用:
第一步:在需要添加getter的属性的属性名前加_(下划线)
第二步:在装饰器@property后面定义一个函数:
函数名就是属性名去掉_(下划线)
函数没有参数,需要一个返回值(返回值就是获取这个属性真正得到的结果)
第三步:通过对象获取属性的时候,属性不需要带_(下划线)

setter

a.什么时候用:如果要在给某个对象属性赋值之前做别的事情,就给这个属性添加setter
b.怎么用:
第一步:在需要添加setter的属性的属性名前加_(下划线)
第二步:在装饰漆@getter名.setter后面定义一个函数:
函数名就是属性名去掉_(下划线)
函数有一个参数(这个参数指向的是赋值的时候赋的值),没有返回值
第三步:通过对象获取属性的时候,属性不需要带_(下划线)

私有化

访问权限

公开的:公开的属性和方法在类的内部和外部都可以用,并且可以被继承
保护的:保护的属性和方法在类的内部可以用,外部不能用,但是可以继承
私有的:私有的属性和方法在类的内部可以用,外部不能用,不能被继承

python中的属性和方法只有一种访问权限:公开的,所有的私有化其实是一种虚拟的私有
私有化的方法:在属性名和方法名前加__(注意:只能是两个__开头,不能再用__结尾)

class Person:
    num = 61
    __info = "动物"

    def __init__(self):
        self.name = "张三"
        self.__age = 18

    def func0(self):
        print(self.name, self.__age)

    @staticmethod
    def func1():
        print(Person.num)
        print(Person.__info)

    @staticmethod
    def __func2():
        return "你好,世界!"

Person.func1()
p1 = Person()
p1.func0()

运算符重载

python在使用运算符的时候本质实在调用运算符对应的方法(函数)
每个运算符对应的方法的方法名是固定的
不同类型的数据在参数相同的运算符的时候,会调用不同类中对应方法
某个类型的数据是否支持某种运算,就看这个数据对应的类型中有没有实现这个运算符对应

class Person:
    def __init__(self, name='小明', age=18, gender='男'):
        self.name = name
        self.age = age
        self.gender = gender

    def __repr__(self):
        return f'<{str(self.__dict__)[1:-1]}>'

    def __lt__(self, other):
        return self.age < other.age


# 练习:将ps中的元素按照年龄的大小从小到大排序
p1 = Person()
p2 = Person('小花', 28, '女')
p3 = Person('张三', 20, '男')
p4 = Person('老王', 25, '男')

# 方法一:添加<魔法方法
ps = [p1, p2, p3, p4]
ps.sort()
print(ps)

# 方法二:
ps.sort(key=lambda item: item.age)
print(ps)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值