小白学习Python的第十八天之面向对象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):
        # 打印哪个对象,self就是谁
        # return f'姓名:{self.name} 电话:{self.tel}'
        return '<'+str(self.__dict__)[1:-1]+'>'
stu1 = Student('小明', '110', score=90)
stu2 = Student('隔壁老王', '120', '0002', 78)
print(stu1)
print(stu2)

1.查 - 获取对象属性的值

"""
对象.属性
getattr(对象, 属性名)
"""
print(stu1.name)
print(getattr(stu1, 'name'))

# 1)getattr可以动态获取属性的值
# value = input('请输入要获取的属性的属性的属性名:')
# print(getattr(stu1, value))

# 2)
# print(stu.height)   # 报错
# print(getattr(stu1, 'height'))   # 报错
# print(getattr(stu1, 'height', 180))   # 180

2.增/改

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

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

3.删 - 删除对象属性

"""
del 对象.属性
delattr(对象, 属性)
"""
del stu1.study_id
print(stu1)

delattr(stu1, 'score')
print(stu1)

二. 类方法和静态方法

1.方法

"""
1)对象方法
怎么定义:直接定义
怎么调用:对象.方法名()
特点:self
什么时候用:如果实现函数的功能需要用到对象属性,那么这个函数就定义成对象方法

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

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

    def __init__(self, name='张三'):
        self.name = name

    # func1是对象方法
    def func1(self):
        print(self.name, Student.num)

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

    @staticmethod
    def func3():
        print('静态方法')
        print(Student.num)


print('Student:', Student)
Student.func2()
Student.func3()

三. getter 和 setter

1.getter和setter

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

2)setter    -   添加setter之前必须先添加getter
a.什么时候用:如果要在给某个对象属性赋值之前做别的什么事情,就给这个属性添加setter
b.怎么用:
第一步:第一步:在需要添加setter的属性的属性名前加_
第二部:在装饰器@getter名.setter后面定义一个函数:
      函数名就是属性名去掉_
      函数有一个参数(这个参数指向的是赋值的时候赋的值),没有返回值
第三步:通过对象给属性赋值的时候,属性不需要带_
"""
class Person:
    def __init__(self):
        self._birth = 0

    @property
    def birth(self):
        t1 = time.localtime(self._birth)
        ts = time.strftime('%Y-%m-%d', t1)
        return ts


p1 = Person()
print(p1.birth)   # 本质是用p1去调用birth方法,获取这个方法的返回值
class Circle:
    pi = 3.1415926

    def __init__(self, radius=10):
        self.radius = radius
        self._area = Circle.pi * radius ** 2

    @property
    def area(self):
        return Circle.pi * self.radius ** 2


c1 = Circle()
print(c1.area)

c1.radius = 100
print(c1.area)
# 练习:给Person添加属性age,要求:age中保存年龄值,获取age属性的时候得到的是
# 这个年龄值对应的阶段状态:儿童(0-4)、少年(5-12)、青年(13-28)、壮年(29-40)、中年(41-55)、老年(55以上)


class Person:
    def __init__(self):
        self._age = 45

    @property
    def age(self):
        if self._age <= 4:
            return '儿童'
        elif self._age <= 12:
            return '少年'
        elif self._age <= 28:
            return '青年'
        elif self._age <= 40:
            return '壮年'
        elif self._age <= 55:
            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()
print(p1.age)   # p1.age()

p1.age = 123   # 本质:p1.age(123)
print(p1.age)

四. 私有化

1.访问权限

"""
1)三种访问权限
公开的:公开的属性和方法在类的内部、外部都可以用,并且可以被继承
保护的:保护的属性和方法在类的内部可以用,外部不能用,但是可以继承
私有的:私有的属性和方法在类的内部可以用,外部不能用,不能被继承

python中的属性和方法只有一种访问权限:公开的,所谓的私有化其实是假的
私有化的方法:在属性名和方法名前加__(注意:只能是两个__开头,不能再用__结尾)
"""
class Person:
    num = 100
    __info = '动物'

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

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

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

    @staticmethod
    def __func2():
        print('你好,世界')


print(Person.num)
# print(Person.__info)
Person.func1()

p1 = Person()
p1.func0()

# Person.__func2()

# print(p1.__dict__)   # 查看私有化数据
# print(p1._Person__age)   # 查看私有化数据

五. 内置类属性

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__)
print(str.__doc__)
  1. 类.module - 获取指定类所在的模块
print(Person.__module__)   # __main__
print(list.__module__)   # builtins
  1. 对象.__ class__ - 获取指定对象对应的类,和type(对象)功能一样
print(p1.__class__)   # <class '__main__.Person'>
print(type(p1))   # <class '__main__.Person'>
print(Person)   # <class '__main__.Person'>
print('abc'.__class__)   # <class 'str'>
  1. 类.__ name__ - 获取类名
print(Person.__name__)   # 'Person'
print(int.__name__)   # 'int'
# 运用:将列表中的不同类型的数据按照自己所属的类型分别保存在文件中(类似str.txt中有'abc','你好')
datas = ['abc', -0.2341, '你好', 34, 90, 12.7]
for data in datas:
    with open(f'files/{data.__class__.__name__}.txt', 'a', encoding='utf-8') as f:
        f.write(str(data)+'\n')
  1. 类.__ dict__ - 将类转换成字典,key是字段名,值是字段对应的值
    对象.__ dict__ - 将对象转换成字典,对象属性名作为key,属性值作为value
print(Person.__dict__)
print(p1.__dict__)

  1. 类.__ base__ - 获取指定类的父类
    类.__ bases__ - 获取指定类所有的父类
print(Person.__base__)   # <class 'object'>
print(Person.__bases__)   # (<class 'object'>,)

object是python中所有类的基类

六. 运算符重载

1.运算符

"""
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]
print(ps)

# 方法一:添加<的魔法方法
# 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、付费专栏及课程。

余额充值