面向对象----反射

一,isinstance和issubclass

isinstance(obj,cls)检查obj是否是类cls的对象

issubclass(sub,super)检查sub类是否是super类的子类

# class A:
#     pass
# class B(A):pass
# a=A()
# b=B()
# print(issubclass(B,A))      #判断一个类是否为一个类的子类
# print(isinstance(a,A))      #判断对象是否为类的对象
# print(isinstance(b,A))

二,反射

1,什么是反射?

主要是指程序可以访问、检测、和修改它本身状态或行为的一种能力。

2,python面向对象中的反射:通过字符串的形式操作对象相关的属性(就是用字符串类型的名字去操作变量),python中一切事物皆对象(都可以使用反射)

四个实现反射的函数

1,getattr,hasattr(一般一起用)

# class A:pass
# class B(A):pass
# a = A()
# print(isinstance(a,A))
# print(issubclass(B,A))
# print(issubclass(A,B))

# 反射 : 是用字符串类型的名字 去操作 变量
# name = 1
# eval('print(name)')  # 安全隐患

# 反射 就没有安全问题

# 反射 : 是用字符串类型的名字 去操作 变量


# 反射对象中的属性和方法   # hasattr getattr setattr delattr
# class A:
#     def func(self):
#         print('in func')
#
# a = A()
# a.name = 'alex'
# a.age = 63
# # 反射对象的属性
# ret = getattr(a,'name')  # 通过变量名的字符串形式取到的值
# print(ret)
# print(a.__dict__)
# 变量名 = input('>>>')   # func
# print(getattr(a,变量名))
# print(a.__dict__[变量名])
#
# # 反射对象的方法
# a.func()
# ret = getattr(a,'func')
# ret()
#
# class A:
#     price = 20
#     @classmethod
#     def func(cls):
#         print('in func')
# # 反射类的属性
# # A.price
# print(getattr(A,'price'))
#
# # 反射类的方法 :classmethod staticmethod
# # A.func()
# if hasattr(A,'func'):
#     getattr(A,'func')()

#模块
# import my
# 反射模块的属性
# print(my.day)
# print(getattr(my,'day'))

# 反射模块的方法
# getattr(my,'wahaha')()

# 内置模块也能用
# time
# asctime
# import time
# print(getattr(time,'time')())
# print(getattr(time,'asctime')())

# def qqxing():
#     print('qqxing')
# year = 2018
# import sys
# # print(sys.modules['__main__'].year)
# # 反射自己模块中的变量
# # print(getattr(sys.modules['__main__'],'year'))
#
# # 反射自己模块中的函数
# # getattr(sys.modules['__main__'],'qqxing')()
# 变量名 = input('>>>')
# print(getattr(sys.modules[__name__],变量名))

# 反射的函数有参数
# print(time.strftime('%Y-%m-%d %H:%M:S'))
# print(getattr(time,'strftime')('%Y-%m-%d %H:%M:S'))

# 一个模块中的类能反射得到
# import my
# print(getattr(my,'C')())
# if hasattr(my,'name'):
#     getattr(my,'name')
用法演示

2,setattr设置修改变量

# class A:
#     pass
# a=A()
# setattr(a,"name","nezha")
# setattr(A,"name","fg")
# print(a.name)
# print(A.name)

3,delattr删除

# 删除  delattr
# delattr(a,"name")
# print(a.name)

三,双下方法

1,__str__和__repr__

# obj.__str__  str(obj)
# obj.__repr__ repr(obj)
# class Teacher:
#     def __init__(self,name,salary):
#         self.name = name
#         self.salary = salary
#     def __str__(self):
#         return "Teacher's object :%s"%self.name
#     def __repr__(self):
#         return str(self.__dict__)
#     def func(self):
#         return 'wahaha'
# nezha = Teacher('哪吒',250)
# print(nezha)  # 打印一个对象的时候,就是调用a.__str__
# print(repr(nezha))
# print('>>> %r'%nezha)
#a.__str__ --> object
# object  里有一个__str__,一旦被调用,就返回调用这个方法的对象的内存地址
# l = [1,2,3,4,5]   # 实例化 实例化了一个列表类的对象
# print(l)
# %s str()  直接打印 实际上都是走的__str__
# %r repr()  实际上都是走的__repr__
# repr 是str的备胎,但str不能做repr的备胎

# print(obj)/'%s'%obj/str(obj)的时候,实际上是内部调用了obj.__str__方法,如果str方法有,那么他返回的必定是一个字符串
# 如果没有__str__方法,会先找本类中的__repr__方法,再没有再找父类中的__str__。
# repr(),只会找__repr__,如果没有找父类的
View Code

2,__len__

# 内置的方法有很多
# 不一定全都在object中
# class Classes:
#     def __init__(self,name):
#         self.name = name
#         self.student = []
#     def __len__(self):
#         return len(self.student)
#     def __str__(self):
#         return 'classes'
# py_s9= Classes('python全栈9期')
# py_s9.student.append('二哥')
# py_s9.student.append('泰哥')
# print(len(py_s9))
# print(py_s9)
View Code

3,__del__

析构方法,当对象在内存中被释放,自动触发执行。

此方法一般无需定义,因为python是一门高级语言,析构函数的调用是由解释器自动触发。

# class A:
#     def __del__(self):
#         print("爸爸执行了")
# a=A()
# del a
# print(">>>>")

4,__call__

对象后面加括号,触发执行。

构造方法的执行是由创建对象触发的,即:对象=类名();而对于__call__方法的执行是由对象后加括号触发的,即:对象()或者类()()

class A:

    def __init__(self, name):
        self.name = name

    def __call__(self):
        '''
        打印这个对象中的所有属性
        :return:
        '''
        for k in self.__dict__:
            print(k, self.__dict__[k])
b= A('alex')()   #执行__call__
#name alex

class A:
    def __init__(self):
        print("sd")
    def __call__(self):
        print("ahi")
a=A()
a()
A()()
#结果
# sd
# ahi
# sd
# ahi
View Code

 5,item系列

getitem  /  setitem  /delitem

# class Foo:
#     def __init__(self,name,age):
#         self.name=name
#         self.age=age
#     def __getitem__(self, item):
#         if hasattr(self, item):
#             return self.__dict__[item]      #查
#     def __setitem__(self, key, value):
#         self.__dict__[key]=value          #增 改
#     def __delitem__(self, key):
#         del self.__dict__[key]        #删
# f=Foo("hi",6)
# f["age"]=12
# print(f["age"])
# f["gao"]=1.77

# print(f["gao"])
# del f["gao"]         #通过自己实现的(__delitem__方法)
# del f.gao          #object 原生支持的
# print(f["gao"])
View Code

6,__new__(构造方法:创建一个对象)

# class A:
#     def __init__(self):
#         self.s=5
#         print("2")
#     def __new__(cls, *args, **kwargs):
#         print("1")
#         return object.__new__(A)
# a1=A()
# a2=A()
# print(a1.s)
View Code
# class A:
#     __instance=False
#     def __init__(self,name,age):
#         self.name=name
#         self.age=age
#     def __new__(cls, *args, **kwargs):
#         if cls.__instance:
#             return cls.__instance
#         cls.__instance=object.__new__(cls)
#         return cls.__instance
# egon=A("egg",45)
# egon.cloth="棍子"
# egon.hi="df"
# print(egon.__dict__)
# na=A("gh",23)
# print(na.__dict__)
# print(egon.__dict__)


只会创建一个对象,新的会覆盖旧的对象
单例模式

7,__hash__

# class A:
#     def __init__(self,name,sex):
#         self.name=name
#         self.sex=sex
#     def __hash__(self):
#         return hash(self.name+self.sex)
# a=A("nazha","ni")
# b=A("nazha","ni")
# print(hash(a))
# print(hash(b))


有__hash__方法得到的哈希值是参数内容的哈希值。
没有__hash__方法得到的哈希值是对象的哈希值。
View Code

8,__eq__

class A:
    def __init__(self,name):
        self.name=name
    def __eq__(self, other):
        if self.__dict__ == other.__dict__:
            return True
        else:
            return False

ob1=A("alex")
oa1=A("alex")
print(ob1==oa1)

__eq__比较内容是否一致
View Code

 注:默认比较内存地址

posted @ 2018-01-25 09:50  一种清孤不等闲  阅读(187)  评论(0编辑  收藏  举报
Live2D