• day28 面向对象:反射,内置函数,类的内置方法


    面向对象进阶博客地址链接:

    http://www.cnblogs.com/Eva-J/articles/7351812.html  

    复习昨日内容:

    #
    # 开发规范
        #
    # hashlib
        # 登录验证 密文密码检测
            # 密文存储
            # 加盐
            # 动态加盐
        # 检测文件一致性   md5
            #MD5.update()
    # configparser : 配置文件相关
        #网络编程 ftp
        #[section1]
        #o1 = yes
    # logging : 日志
        #记录一些信息和结果
        #打日志
        #日志就和print
        #学生管理系统
            #需要用户选择的时候打印的提示信息
            #一个程序和用户发生文字交互的时候,不能使用logging
        # 中间结果 错误提示 都可以使用logging
        # 管理员在某时某刻创建了一个班级 —— logging
    View Code

    今日概要:

    # 欠你得内置函数  ***
    # 反射 *****
    # 类的内置双下方法 ***
    # 面向对象的高级代码和一道面试题
        # 看书
        # 看源码
        # 看博客
            #简书
            #csdn
    View Code

    内置函数:

    #property
    #classmethod
    #staticmethod
    #super
    #object
    #isinstance
    #issubclass
    #vars
    # from collections import Iterable
    # print(isinstance([],Iterable))
    
    # class A:pass
    # class B(A):pass
    # b = B()
    # print(isinstance(b,A))
    # print(isinstance(a,object))
    
    # class A:pass
    # class B(A):pass
    # print(issubclass(B,A))
    # print(issubclass(A,B))
    # print(issubclass(A,object))
    # print(issubclass(B,object))
    
    #isinstance(对象,类) 判断这个对象是不是这个类或者这个类的子类的实例化
    
    #看全局
    # a = 1
    # b = 2
    # print(vars())
    # print(dir())
    
    class A:
        '''
        描述管理员的类
        '''
        c = 1
        d = 2
        def func(self,name):
            '''
            这个函数整体是做什么的
            :param name: 管理员的姓名
            :return: 管理员的信息
            '''
            self.name = 'alex'
    
    #看类
    # print(vars(A))
    a = A()
    a.func()
    
    #看对象
    print(vars(a))
    
    '''
           这个函数的主要功能
    
           :return: 
           '''
    View Code

    反射:这个很重要,必须要学会!

    # hasattr()
    # getattr()
    # setattr()
    # delattr()
    # a = 1
    # name = 'a'
    # print(vars())
    # print(vars()[name])
    # eval()
    class Management:
        role = '管理员'
        def __init__(self,name,sex,phone,mail):
            self.name = name
            self.sex = sex
            self.phone = phone
            self.mail = mail
    
        def creat_class(self):
            print('创建了一个班级')
    
        def creat_teacher(self):
            print('新建了一条讲师信息')
    
        def creat_student(self):
            print('新建了一条学生信息')
    # Management.role
    # if hasattr(Management,'role'):
    #     print(getattr(Management,'role'))
    # import logging
    # manager = Management('小雨','女',1233211234567,'xiaoyu@qq.com')
    # if hasattr(manager,'sex1'):
    #     sex = getattr(manager,'sex1')  #使用字符串数据类型的变量名获取属性值
    #     print(sex)
    # else:
    #     logging.warning('没有您输入的属性')
    # cs = getattr(manager,'creat_class') #使用字符串数据类型的方法名调用方法
    # cs()
    # Management.Country = 'China'
    # setattr(Management,'Country','China')
    # print(Management.Country)
    # del Management.Country
    # delattr(Management,'Country')
    # print(Management.Country)
    
    # manager = Management('小雨','女',1233211234567,'xiaoyu@qq.com')
    # manager.hobby = '点名'
    # setattr(manager,'hobby','点名')
    # print(manager.hobby)
    
    #可以通过delattr删除一个类中的方法
    # delattr(Management,'creat_class')
    # manager.creat_class()
    
    # def create_course(self):
    #     print('创建了一个课程')
    
    # setattr(manager,'create_course',create_course)
    # manager.create_course(manager)
    
    # hasattr(对象名,'属性名')  返回True或False
    #属性值 = getattr(对象名,'属性名')
    #方法的内存地址 = getattr(对象名,'方法名')
    #方法的内存地址()
    
    
    # import demo
    # # demo.a
    # print(getattr(demo,'a'))
    # qq = getattr(demo,'qqxing')
    # ret = qq('wahaha')
    # print(ret)
    
    # aaa = 'bbb'
    # import sys
    # print(sys.modules[__name__])
    # print(getattr(sys.modules[__name__],'aaa'))
    
    # 对象的反射
    # 类的反射
    # 模块的反射
    # 本模块的反射 : 找到本模块sys.modules[__name__]
    View Code

     反射包括在类中对象的反射,类的反射,以及模块的反射,还有程序所处当前位置的本模块的反射。

    类的内置方法:

    #str 和 repr
    # class A:
    #     # pass
    #     def __str__(self):
    #         return 'A的对象'
    
        # def __repr__(self):
        #     return 'repr: A的对象'
    
    
    # a = A()
    # print(a)  #本质调用的是__str__,如果没实现,就调用__repr__, 再找不到,用object父类的
    # print(a.__str__())  #str却不能给repr做备胎
    # print(a.__repr__()) #repr是str的备胎
    # 打印一个对象的时候,实际上是调用了这个对象所在类的__str__方法,打印的是这个方法的返回值
    # print(str(a))
    # print(repr(a))
    # print('%s'%a)
    # print('%r'%a)
    
    
    
    # print(a)
    # l = list()
    # print(l)
    
    # format_dict={
    #     'nat':'{o.name}-{o.addr}-{o.type}',#学校名-学校地址-学校类型
    #     'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
    #     'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
    # }
    # class School:
    #     def __init__(self,name,addr,type):
    #         self.name=name
    #         self.addr=addr
    #         self.type=type
    #
    #     def __format__(self, format_spec): #format_spec = 'nat'
    #         fmt='''=====================
    # 姓名 : {obj.name}
    # 班级 : {obj.addr}
    # ====================='''
    #         return fmt.format(obj=self)
    
    # s1=School('oldboy1','北京','私立')
    # print(format(s1,'nat'))
    # print(format(s1,'tna'))
    # print(format(s1,'tan'))
    # print(format(s1,'asfdasdffd'))
    
    #打印学生信息
    #姓名 班级 性别 年龄
    #=====================
    # 姓名 : name
    # 班级 : class
    #=====================
    
    # 析构方法
    # 周期 :0
    # 12  一个亿个对象 del 对象
    # class A:
    #     def __del__(self):
    #         '''
    #         析构方法
    #         这个方法只有在执行del A类的对象的时候才被触发
    #         且先执行代码中的内容,再删除对象
    #         如果我删除了这个对象,它跟着还有一些其他的附属的内容也没有用了
    #         我们就可以在这个方法中回收掉
    #         '''
    #         print('执行我啦!')
    #         self.b.close()
    # f = open('file','w')
    # a = A()
    # a.b = f
    # del a
    # print(a)
    
    class Foo:
        def __init__(self,name):
            self.name=name
        def __getitem__(self, item):
            if item == 1:
                print('hahaha')
            # print(self.__dict__[item])
        def __setitem__(self, key, value):
            self.__dict__[key]=value
        def __delitem__(self, key):
            print('del obj[key]时,我执行')
            self.__dict__.pop(key)
        def __delattr__(self, item):
            print('del obj.key时,我执行')
            self.__dict__.pop(item)
    
    f1 = Foo('sb')
    #访问属性的方式变了
    #对象名.属性
    # f1=Foo('sb')
    # f1['age']=18  #给f1添加一个属性
    # del f1['age']  #删除属性
    # # f1.name
    # print(f1['name'])
    #
    # f1.__dict__['age'] = 18
    # f1['age1']=19
    # del f1.age1   #删除属性
    #
    # f1['name']='alex'
    # print(f1.__dict__)
    
    #pytho内部的约定
    
    #关于item : 对象访问 如果是 对象名[],是因为内部实现了item系列的方法
    
    # 对象的实例化
        #创造一个裸地对象 —— __new__  ****
        #初始化
    # 单例模式 —— 设计模式
    # 一个类 从头到尾 只创建 一个对象
    # class Singleton:
    #     def __new__(cls, *args):
    #         if not hasattr(cls, '_instance'):
    #             cls._instance = object.__new__(cls)
    #         return cls._instance
    #
    #     def __init__(self,name):
    #         self.name = name
    #
    # one = Singleton('alex')
    # print(one.name)
    # two = one
    # two.name = 'egon'
    # # two = Singleton('egon')
    # # print(two.name)
    # # print(one.name)
    # print(id(one),id(two))
    
    # class Foo:
    #     def __init__(self):
    #         pass
    #
    #     def __call__(self, *args, **kwargs):
    #         print('__call__')
    #
    # Foo()()   #对象名()
    
    # class A:
    #     def __eq__(self,obj):   #equal : 相等
    #         # if  self.a == obj.a and self.b == obj.b:
    #             return True
    # a = A()
    # b = A()
    # a.name = 'alex'
    # b.name = 'egon'
    # print(a == b)
    # from collections import namedtuple
    # Card = namedtuple('Card',['rank','suit'])
    # class FranchDeck:
    #     ranks = [str(n) for n in range(2,11)] + list('JQKA')
    #     suits = ['红心','方板','梅花','黑桃']
    #     def __init__(self):
    #         self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
    #                                         for suit in FranchDeck.suits]
    #
    #     def __len__(self):
    #         return len(self._cards)
    #
    #     def __getitem__(self, item):
    #         return self._cards[item]
    #
    #     def __setitem__(self, key, value):
    #         self._cards[key] = value
    #
    # deck = FranchDeck()
    # # print(deck._cards)
    # print(deck[0])
    # # from random import choice
    # # print(choice(deck))
    # # print(choice(deck))
    # from random import shuffle
    # shuffle(deck)
    # print(deck._cards)
    
    # 一个类 有 100个 对象,每一个对象都拥有三个属性:name,sex,age
    # 如果两个对象的name和sex属性完全一致
    # 我就认为这是一个对象
    # 请对这100个对象进行去重
    # class Person:
    #     def __init__(self,name,age,sex):
    #         self.name = name
    #         self.age = age
    #         self.sex = sex
    #     def __hash__(self):
    #         return hash(self.name+self.sex)
    #     def __eq__(self, other):
    #         if self.name == other.name and self.sex == other.sex:return True
    #
    # p_lst = []
    # for i in range(84):
    #     p_lst.append(Person('egon',i,'male'))
    # print(set(p_lst))
    View Code

     下面这一版的内置方法是添加了更多的更详尽注释的:

    # str 和 repr
    # class A:
    #     # pass
    #     def __str__(self):
    #         return 'A的对象'
    
        # def __repr__(self):
        #     return 'repr: A的对象'
    
    
    # a = A()
    # print(a)  # 本质调用的是__str__,如果没实现,就调用__repr__, 再找不到,用object父类的
    # print(a.__str__())  # str却不能给repr做备胎
    # print(a.__repr__()) # repr是str的备胎
    # 打印一个对象的时候,实际上是调用了这个对象所在类的__str__方法,打印的是这个方法的返回值
    # print(str(a))
    # print(repr(a))
    
    # print('%s'%a)
    # print('%r'%a)
    # print(a)
    # l = list()
    # print(l)
    
    # format_dict={
    #     'nat':'{o.name}-{o.addr}-{o.type}',#学校名-学校地址-学校类型
    #     'tna':'{obj.type}:{obj.name}:{obj.addr}',#学校类型:学校名:学校地址
    #     'tan':'{obj.type}/{obj.addr}/{obj.name}',#学校类型/学校地址/学校名
    # }
    # class School:
    #     def __init__(self,name,addr,type):
    #         self.name=name
    #         self.addr=addr
    #         self.type=type
    #
    #     def __format__(self, format_spec): #format_spec = 'nat'
    #         fmt='''=====================
    # 姓名 : {obj.name}
    # 班级 : {obj.addr}
    # ====================='''
    #         return fmt.format(obj=self)
    
    # s1=School('oldboy1','北京','私立')
    # print(format(s1,'nat'))
    # print(format(s1,'tna'))
    # print(format(s1,'tan'))
    # print(format(s1,'asfdasdffd'))
    
    # 打印学生信息
    # 姓名 班级 性别 年龄
    # =====================
    # 姓名 : name
    # 班级 : class
    # =====================
    
    # 析构方法
    # 周期 :0
    # 12  一个亿的对象 del 对象
    # class A:
    #     def __del__(self):
    #         '''
    #         析构方法
    #         这个方法只有在执行del A类的对象的时候才被触发
    #         且先执行代码中的内容,再删除对象
    #         如果我删除了这个对象,它跟着还有一些其他的附属的内容也没有用了
    #         我们就可以在这个方法中回收掉
    #         '''
    #         print('执行我啦!')
    #         self.b.close()  ## 这里self就是a,self是实例化的对象,所以a.b就是self.b
    #  所以这里也解释了为什么这里的b要和下面a后面的b保持一致的原因
    # f = open('file','w')
    # a = A()
    # a.b = f  ## 这里是添加一个属性,a是A实例化出来的一个对象,a.b = f 这是把对象所添加的属性赋值给f
    # del a
    # print(a)
    
    
    class Foo:
        def __init__(self,name):
            self.name=name
    
        def __getitem__(self, item):
            if item == 1:
                print('hahaha')
            # print(self.__dict__[item])
    
        def __setitem__(self, key, value):
            self.__dict__[key] = value
    
        def __delitem__(self, key):
            print('del obj[key]时,我执行')
            self.__dict__.pop(key)
    
        def __delattr__(self, item):
            print('del obj.key时,我执行')
            self.__dict__.pop(item)
    
    
    f1 = Foo('sb')
    # 访问属性的方式变了
    # 对象名.属性
    # f1=Foo('sb')
    # f1['age']=18  #给f1添加一个属性
    # del f1['age']  #删除属性
    # # f1.name
    # print(f1['name'])
    #
    # f1.__dict__['age'] = 18
    # f1['age1']=19
    # del f1.age1   #删除属性
    #
    # f1['name']='alex'
    # print(f1.__dict__)
    
    #pytho内部的约定
    
    #关于item : 对象访问 如果是 对象名[],是因为内部实现了item系列的方法
    
    # 对象的实例化
        # 创造一个裸地对象 —— __new__  ****
        # 初始化
    # 单例模式 —— 设计模式
    # 一个类 从头到尾 只创建 一个对象
    # class Singleton:
    #     def __new__(cls, *args):
    #         if not hasattr(cls, '_instance'):
    #             cls._instance = object.__new__(cls)
    #         return cls._instance
    #
    #     def __init__(self,name):
    #         self.name = name
    #
    # one = Singleton('alex')
    # print(one.name)
    # two = one
    # two.name = 'egon'
    # # two = Singleton('egon')
    # # print(two.name)
    # # print(one.name)
    # print(id(one),id(two))
    
    # class Foo:
    #     def __init__(self):
    #         pass
    #
    #     def __call__(self, *args, **kwargs):
    #         print('__call__')
    #
    # Foo()()   #对象名()
    
    # class A:
    #     def __eq__(self,obj):   #equal : 相等
    #         # if  self.a == obj.a and self.b == obj.b:
    #             return True
    # a = A()
    # b = A()
    # a.name = 'alex'
    # b.name = 'egon'
    # print(a == b)
    # from collections import namedtuple
    # Card = namedtuple('Card',['rank','suit'])
    # class FranchDeck:
    #     ranks = [str(n) for n in range(2,11)] + list('JQKA')
    #     suits = ['红心','方板','梅花','黑桃']
    #     def __init__(self):
    #         self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
    #                                         for suit in FranchDeck.suits]
    #
    #     def __len__(self):
    #         return len(self._cards)
    #
    #     def __getitem__(self, item):
    #         return self._cards[item]
    #
    #     def __setitem__(self, key, value):
    #         self._cards[key] = value
    #
    # deck = FranchDeck()
    # print(deck._cards)
    # print(deck[0])
    # # from random import choice
    # # print(choice(deck))
    # # print(choice(deck))
    # from random import shuffle
    # shuffle(deck)
    # print(deck._cards)
    
    # 一个类 有 100个 对象,每一个对象都拥有三个属性:name,sex,age
    # 如果两个对象的name和sex属性完全一致
    # 我就认为这是一个对象
    # 请对这100个对象进行去重
    
    
    class Person:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def __hash__(self):  # 这里使用hash方法把字符串拼接起来,得到一个新的字符串,
            # 如果得到的新的字符串都相同那么这两个元素就是想等的,不仅仅是字符串可以用hash,hash是不可变的数据类型,
            # (可hash不可变数据类型)
            return hash(self.name+self.sex)
    
        def __eq__(self, other):  # 我们去重需要使用集合,因为集合的最大特点就是去重,那么集合里面不仅仅是包含了不可变
            # 数据类型,还有可变数据类型,当我们遇到可变数据类型的时候那么我们就需要使用eq去判断他们的值是否相等了,
            # 这样使得程序更加趋于完善,可以hold住更多的可能
            if self.name == other.name and self.sex == other.sex:return True
    
    
    p_lst = []
    for i in range(84):
        p_lst.append(Person('egon', i, 'male'))
    print(set(p_lst))
    
    # 一句话总结就是可hash属于不可变的数据类型,需要使用hash去判断是否相等,
    # 那么不可hash可变的数据类型呢,就不能够使用hash去判断了,需要使用eq去判断是否相等
    View Code
  • 相关阅读:
    CS027th: 6papers
    MATH026th: 《矩斋筹算丛刻》
    MATH026th: 《古今算学丛书》目录
    Compiler25th005: Excel Compiler
    AIIE25th004: 2020aiie在合肥举办
    AIIE21th003: 2021年第二届国际工业工程和人工智能大会(IEAI 2021)
    ComPiler200004:Library-Oriented Programming
    ComPiler200003:Story-Oriented Programming
    ComPiler200002:Growing a Compiler
    conda
  • 原文地址:https://www.cnblogs.com/2012-dream/p/7894710.html
Copyright © 2020-2023  润新知