day31 Pyhton 面向对象的基础 三大特性

时间:2022-12-15 19:20:04

一.内容回顾

封装

  1.概念 笔记

  2.__名字 在类的外部就不能用了

  3.私有化的 不能被子类继承,也不能在其他任何类中调用

三个装饰器方法(装饰类中的方法)

  1.不被修饰的  普通方法,会使用对象self的属性

  2.@classmethod  类方法,不使用self的属性,用类cls的属性

  3.@staticmethod 静态方法,不用self的属性和类cls的属性

  4.@property  将一个方法伪装成一个属性

    def  函数名

    @函数名.setter

    @函数名.deleter

# from math import pi
# class Circle:
#     def __init__(self,r):
#         self.r = r
#     @property
#     def area(self):
#         return pi*self.r**2
#     @property
#     def perimeter(self):     # 周长
#         return 2*pi*self.r
#     @perimeter.setter
#     def perimeter(self,新的周长):
#         self.r = 新的周长 / 2 / pi

setter修改属性值

# setter装饰的函数名叫什么 perimeter

# 那么在这个函数中绝对不可以对这个函数名同名的属性进行修改
# 程序的逻辑问题
    # 1. 不可以对某些计算结果直接赋值
    # 2. 一般是通过对计算结果产生影响的属性进行重新赋值
    # 比如说对于圆这个例子 : 不能直接修改面积或者周长,应该通过修改半径来带动对应周长和面积的改变
# 反射(不得不用)
# 使用字符串的方式,操作对象的属性(对象属性,类的动态属性(方法))
# 在python中 一切皆对象(类也是对象,对象也是对象,模块也是对象)
# a.b
# a就是一个对象
# b本质上是一个变量名,也可以说是a的一个属性
# 如果b是b 那么就用a.b
# 如果b是'b' 那么就用getattr(a,'b')

二.面向对象的基础
三大特性

  基础的继承

  基础的封装 __私有

两个内置函数:issubclass  isinstance

反射: setattr/delattr  了解

内置方法: 你没有应用场景

__new__

__call__

__str__/__repr__

__len__

__***item__系列

__hash__

__eq__

issubclass(子类,父类),如果真的有继承关系,就返回True

class A(object):pass
class B(A):pass
print(issubclass(B,A))
# isinstance(对象,类)
# class A(object):pass
# a = A()
# print(isinstance(a,A))
# # 继承
# class A(object):pass
# class B(A):pass
# b = B()
# print(isinstance(b,A)) # 检测的对象是不是某个类以及其父类的对象
# print(type(b) is B)  # 检测的是对象是不是某一个类的实例
# print(type(b) is A)
所有的反射 都是用字符串 操作对象的属性
class A:
    def __init__(self,name,age):
        self.name = name
        self.age = age

a = A('alex',83)
# hasattr
# print(getattr(a,'name'))#alex
# a.sex = '不详'
# setattr(a,'sex','不详')
# print(a.sex)#不详
del a.age
# delattr(a,'age')
print(a.__dict__)#{'name': 'alex', 'sex': '不详'}
 
# 关于内置方法的名字
    # 内置方法 双下方法 魔术方法
# 内置方法的特点
    # 一定有某一个语法或者一种写法自动触发这个方法
 
# 重点掌握的
    # 哪些写法 触发 对应的内置方法
    # 实例化        __new__\__init__   构造方法(单例模式)\初始化方法
    # 对象()        __call__
    # del 对象      __del__            析构方法\对象删除之前的收尾工作
    # print(对象)   __str__            让一个对象的显示更加清晰
    # str(对象)
    # '%s'%对象
    # repr()        __repr__           是__str__的备胎,并且还和repr(),%r格式化有关系
    # '%r'%对象
    # len(对象)     __len__
    # 对象[参数]    item系列
    # ==           __eq__
__call__ 对象用call方法可以调用函数__call__里的方法
# __call__
class Student():
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def call(self):pass
    def __call__(self, *args, **kwargs):
        print('调用我啦')
alex = Student('alex',83)
# callable #查看某个变量能否被调用
# callable(变量)  #返回True,那么 变量() --> 调用
print(callable(Student))#True
print(callable(alex))#True
# alex()
alex.call()#调用我啦
 
class Dog(object):
    def __new__(cls, *args, **kwargs):
        pass
        dog_obj = object.__new__(cls)#调用父类object的__new__内置方法
        dog_obj = super().__new__(cls)##调用父类object的__new__内置方法,第二种方法
        return dog_obj
    def __init__(self,name,age):
        self.name = name
        self.age = age

wc = Dog('旺财',2)
print(wc.name)
 
# 一个类 只能实例化一次的方法
class Teacher:
    flag = None
    def __new__(cls, *args, **kwargs):
        if cls.flag is None:
            cls.flag = object.__new__(cls)    # 这一句话只能走一次
        return cls.flag
    def __init__(self,name):
        self.name = name

alex1 = Teacher('alex')
alex2 = Teacher('alex')
yuan = Teacher('yuan')
print(alex2.name)#yuan
print(yuan.name)#yuan
__del__
# 析构方法(了解) 删除
class Teacher:
    def __init__(self,name):
        self.name = name
    def __del__(self):
        print('执行我啦')

alex = Teacher('ALEX')
del alex
print('hahaha')
 
# del alex    # 执行del 对象的时候 触发__del__,在真正的删除alex对象之前,执行的方法__del__
# 如果我们自己不删除alex,那么在程序的执行过程中或者最后,垃圾回收机制会替你执行del alex
# 1.del alex
# 2.执行__del__
# 3.删除alex
 
class File(object):
    def __init__(self,file_name):
        self.f = open('file_name')
    def read(self):
        self.f.read(1024)
    def  __del__(self):# 对象使用的一些操作系统的资源的归还工作/收尾工作
        self.f.close()
__str__
class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    def __str__(self):  # 必须有返回值,必须返回一个str类型
        return '%s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)
course_lst = []
python = Course('python',19800,'6 months','baoyuan')
linux = Course('linux',16800,'5 months','oldboy')
print(python)
print(str(python))
print('课程展示 : %s'%python)
 
class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    def __str__(self):  # 必须有返回值,必须返回一个str类型
        return '%s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)
course_lst = []
python = Course('python',19800,'6 months','baoyuan')
linux = Course('linux',16800,'5 months','oldboy')
print(python)
print(str(python))
print('课程展示 : %s'%python)
 
# list.__str__()
l = [1,2,3,4] # 对象 列表的对象
print(l)
print('[%s,%s,%s]'%(l[0],l[1],l[2]))
__repr__ 是str方法的备胎(有str调用str,没有str走repr)
class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    def __repr__(self):  # 必须有返回值,必须返回一个str类型
        return 'repr --> : %s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)
    def __str__(self):  # 必须有返回值,必须返回一个str类型
        return 'str --> : %s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)

python = Course('python',19800,'6 months','baoyuan')
linux = Course('linux',16800,'5 months','oldboy')
print(python)
print(linux)
 
class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    def __repr__(self):  # 必须有返回值,必须返回一个str类型
        return 'repr --> : %s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)
    def __str__(self):  # 必须有返回值,必须返回一个str类型
        return 'str --> : %s,%s,%s,%s'%(self.name,self.price,self.period,self.teacher)
python = Course('python',19800,'6 months','baoyuan')
linux = Course('linux',16800,'5 months','oldboy')
print('%r'%python)#repr --> : python,19800,6 months,baoyuan
print('%s'%python)#str --> : python,19800,6 months,baoyuan
print(str(python))#str --> : python,19800,6 months,baoyuan
print(repr(python))#repr --> : python,19800,6 months,baoyuan
 
# 流畅的python : repr和str 如果只能写一个的 写repr
 
class Course:
    def __init__(self,name,price,period,teacher):
        self.name = name
        self.price = price
        self.period = period
        self.teacher = teacher
    def __len__(self):
        return len(self.__dict__)
    def __getitem__(self,item):
        return self.__dict__[item]
    def __setitem__(self, key, value):
        self.__dict__[key] = value
    def __delitem__(self, key):
        self.__dict__.pop(key)
python = Course('python',19800,'6 months','baoyuan')
print(len(python))
print(python.name)
print(python['name'])  # ==> 调用getitem
print(python['price'])  # ==> 调用getitem
python['name'] = 'python2.0'
print(python.name)
# del python.name#与下一句功能一样
del python['name']
print(python.__dict__)#{'price': 19800, 'period': '6 months', 'teacher': 'baoyuan'}
# 有一些内置的函数/模块 要想能正确的使用它们 那么必须按照它规定的语法来实现
__len__ 测量对象长度
class Ruler:
    def __init__(self,price,length,jingdu):
        self.length = length
        self.price = price
        self.jingdu = jingdu
    def __len__(self):
        return self.length
stu_ruler = Ruler(2.5,15,0.1)
print(len(stu_ruler))#15
__eq__ s1==s2 等于 s1.__eq__(s2)
class Student():
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __eq__(self, other):
        if self.name == other.name and self.age == other.age:
            return True
        return False

s1 = Student('贾卫东',20)
s2 = Student('贾卫东',20)
print(s1 == s2)   # s1.__eq__(s2)#True
print(s1 is s2)   # s1.__eq__(s2)#False
#够通过这个字符串 --> 程序中的变量名(类名\函数名\变量名\方法名\对象名)
class Manager:pass
class Student:pass
class Teacher:pass
identify = 'Student'
print(eval(identify)())#<__main__.Student object at 0x00000000025657B8>

反射 hasattr getattr

class Person:
    role = '人类'
    Country = '中国'

attr = input('>>>')  # role 人类
#                    # Country 中国
print(getattr(Person,'role'))
print(getattr(Person,'Country'))
if hasattr(Person,attr):
    print(getattr(Person,attr))

if attr == 'role':
    print(Person.role)
elif attr == 'Country':
    print(Person.Country)
class Person:
    role = '人类'
    @staticmethod
    def show_courses():
        print('所有课程')
# 反射类中的方法
# class Person:
#     role = '人类'
#     @staticmethod
#     def show_courses():
#         print('所有课程')
# Person.role  == getattr(Person,'role')
# Person.show_courses() == getattr(Person,'show_courses')()
# ret = getattr(Person,'show_courses')
# ret()
# 有一个类,有很多静态属性,也有很多静态方法/类方法
# 用户输入input任意的属性名或者方法名,
# 如果是属性 直接打印  - 用到一个内置函数#getattr(Person,'role')
# 如果是方法 直接调用  - 用到一个内置函数#getattr(Person,'show_courses')
# 要求程序不报错