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
原文地址:https://www.cnblogs.com/2012-dream/p/7894710.html