python之isinstance和issubclass,反射,内置方法

isinstance和issubclass

isinstance(obj,cls)检查是否obj是否是类 cls 的对象。对象与类之间的关系

class B:pass
class A(B):pass
a = A()
print(isinstance(a, A))        #结果:True
print(isinstance(a, B))  # 能够检测到继承关系 结果:True
print(type(a) is A)           #结果:True
print(type(a) is B)   # type只单纯的判断类 结果:False

issubclass(sub, super)检查sub类是否是 super 类的派生类,类与类之间的关系

issubclass(子类名,父类名) 如果返回True,说明有继承关系

class B:pass
class C(B): pass
class D(C):pass
print(issubclass(C, D))
print(issubclass(D,C))
print(issubclass(B,C))
print(issubclass(C,B))
print(issubclass(D,B))

反射

python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数,类中的反射 类可以获取类中的属性和方法

下列方法适用于类和对象(一切皆对象,类本身也是一个对象) 反射有四种方法:

hasattr:hasattr(object,name)判断一个对象是否有name属性或者name方法。有就返回True,没有就返回False

getattr:获取对象的属性或者方法,如果存在则打印出来。hasattr和getattr配套使用

需要注意的是,如果返回的是对象的方法,返回出来的是对象的内存地址,如果需要运行这个方法,可以在后面添加一对()

setattr:给对象的属性赋值,若属性不存在,先创建后赋值

delattr:删除该对象指定的一个属性
具体来看一下:

hasattr() 判断一个命名空间中有没有这个名字

def hasattr(*args, **kwargs): # real signature unknown
    """
    Return whether the object has an attribute with the given name.
     
    This is done by calling getattr(obj, name) and catching AttributeError.
    """
    pass

getattr() 从命名空间中获取这个名字对应的值

def getattr(object, name, default=None): # known special case of getattr
    """
    getattr(object, name[, default]) -> value
     
    Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
    When a default argument is given, it is returned when the attribute doesn't
    exist; without it, an exception is raised in that case.
    """
    pass 

setattr # 修改和新建

def setattr(x, y, v): # real signature unknown; restored from __doc__
    """
    Sets the named attribute on the given object to the specified value.
     
    setattr(x, 'y', v) is equivalent to ``x.y = v''
    """
    pass

delattr # 删除一个属性

def delattr(x, y): # real signature unknown; restored from __doc__
    """
    Deletes the named attribute from the given object.
     
    delattr(x, 'y') is equivalent to ``del x.y''
    """
    pass

在反射中有这四种,四种方法的实例

hasattr,getattr一起使用

class A:
    role = 'person'
    def funx(self):
        print('***'*self)
print(hasattr(A, 'role'))          #结果:True
print(hasattr(A, 'funx'))           #结果:True
ret = input('>>>>')
if hasattr(A, ret):
    print(getattr(A, ret))
elif hasattr(A, ret):
    func = getattr(A, ret)
    func(1)

class A:
    role = 'Person'
    def __init__(self):
        self.money = 500
    def func(self):
        print('*'*10)
 
a = A()
print(a.func)
getattr(a,'func')()
print(getattr(a,'money'))

*类使用类命名空间中的名字,对象使用对象能用的方法和属性,模块使用模块中的名#,import os ; getattr(os,‘rename’)(‘user’,‘user_info’)

import time   # 一个py文件就是一个模块
time.time()
print(time.time())
print(getattr(time,'time')())
 
import os
os.rename('userinfo','user')
getattr(os,'rename')('user','user_info')

从自己所在的模块中使用自己名字

def login():
    print('执行login功能')
 
def register():
    print('执行register功能')
 
import sys  # 和python解释器相关的内容都在sys里
print(sys.modules['__main__'])
func = input('>>>')
if hasattr(sys.modules['__main__'],func):
    getattr(sys.modules['__main__'],func)()

类使用类命名空间中的名字 # getattr(类名,‘名字’) # 对象使用对象能用的方法和属性 # getattr(对象名,‘名字’) #
模块使用模块中的名字 # 导入模块 # getattr(模块名,‘名字’) # import os ;
getattr(os,‘rename’)(‘user’,‘user_info’) # 从自己所在的模块中使用自己名字 # import
sys # getattr(sys.modules[‘main’],名字) # getattr一定要和hasattr配合使用<em
id="__mceDel" style=“background-color: #ffffff; font-family: “PingFang
SC”, “Helvetica Neue”, Helvetica, Arial, sans-serif; font-size: 14px”>

增删(setattr,delattr)改 对象属性

class A:
    def __init__(self,name):
        self.name = name
 
    def wahaha(self):
        print('wahahahahaha')
 
a = A('alex')
a.wahaha()
#a.age = 18
#print(a.__dict__)
setattr(a,'age',18)   # 给a对象新增一个属性
print(a.__dict__)
setattr(a,'name','egon')
print(a.__dict__)
#del a.age
delattr(a,'age')
print(a.__dict__)

增删改 方法

class A:
    def __init__(self,name):
        self.name = name
 
    def wahaha(self):
        print('wahahahahaha')
 
def qqxing(self):
    print('qqqqqxing')
 
a = A('alex')
setattr(A,'qqxing',qqxing)
setattr(a,'qqxing',qqxing)
print(a.__dict__)
a.qqxing(a)

内置方法

__ len__

有一个内置函数 和内置方法len()是唯一对应的关系,len() obj.len() 返回值是一致的len() 的结果是依赖 ***obj.***__ len__

class A:
    def __init__(self,name,age,sex,cls):
        self.name = name
        self.age = age
        self.sex = sex
        self.cls = cls
    def __len__(self):
        return len(self.__dict__)
a1 = A('aa',81,'男',2)
print(len(a1))

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

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

class Teacher():
    def __call__(self):
        print(123)
    def call(self):
        print(456)
t = Teacher()
t.call()          
t()             # 对象名() 相当于调用类内置的__call__

一个对象是否可调用 完全取决于这个对象对应的类是否实现了__call__
__ new__
构造方法
实例化的时候
创造对象的过程 new
init 初始化
设计模式 —— 单例模式
单例模式 就是 一个类 只能有一个实例

class B:
    __instance = None
    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            obj = object.__new__(cls)
            cls.__instance = obj
        return cls.__instance
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def func(self):
        print(self.name)
a = B('alex',80)
b = B('egon',20)
print(a)
print(b)
print(a.name)
print(b.name)

__ del__
析构方法: 在删除一个对象的时候做一些首尾工作

class A:
    def __init__(self):
        self.f = open('文件','w')
    def __del__(self):
        self.f.close()
        print('执行我啦')
a = A()
del a
print(a)
print('aaa')

__ hash__字典的存储 hash
hash() 的结果是依赖 obj.hash()

class A:
    def __init__(self,name,age,sex,cls):
        self.name = name
        self.age = age
        self.sex = sex
        self.cls = cls
    def __hash__(self):
        return hash(str(self.name) + str(self.age))
a1 = A('aa',31,'女',2)
print(hash(a1))

__ eq__
== 是由__eq__的返回值来决定的

class A:
    def __eq__(self, other):
        # if self.__dict__ == other.__dict__:
            return True

__ eq__()

a = A()
a.name = 'alex'
b = A()
b.name = 'egon'
print(a)
print(b)
print(a == b)

__ str__和__ repr__ __ format__
改变对象的字符串显示__str__,repr

当需要使用__str__的场景时找不到 str__就找__repr
当需要使用__repr__的场景时找不到__repr__的时候就找父类的repr
双下repr是双下str的备胎
str() 的结果是依赖 obj.str()
print(obj) 的结果是依赖 obj.str()
%s 的结果是依赖 obj.str() # 语法糖
repr() 的结果是依赖 obj.repr()
%r 的结果是依赖 obj.repr()
自定制格式化字符串__format__

format_dict = {
    'nat': '{obj.name}-{obj.addr}-{obj.type}',
    'tna': '{obj.name}:{obj.addr}:{obj.type}',
    'ant': '{obj.name}/{obj.addr}/{obj.type}'
}
class School:
    def __init__(self, name, addr, type):
        self.name = name
        self.addr = addr
        self.type = type
    def __repr__(self):
        return 'school(%s, %s)' % (self.name, self.addr)
    def __str__(self):
        return '(%s,%s)'% (self.name, self.addr)
    def __format__(self, format_spec):
        if not format_spec or format_spec not in format_dict:
            format_spec = 'nat'
        fmt = format_dict[format_spec]
        return fmt.format(obj=self)
s1=School('oldboy1','北京','私立')
print('from repr: ',repr(s1))
print('from str: ',str(s1))
print(s1)
print(format(s1,'nat'))
print(format(s1,'tna'))
print(format(s1,'tan'))
print(format(s1,'asfdasdffd'))

‘’‘str函数或者print函数—>obj.str()
repr或者交互式解释器—>obj.repr()
如果__str__没有被定义,那么就会使用__repr__来代替输出
注意:这俩方法的返回值必须是字符串,否则抛出异常’’’
  %s 和%r
 %s执行的就是__str__

%r执行的就是__repr__

class B:
 
     def __str__(self):
         return 'str : class B'
 
     def __repr__(self):
         return 'repr : class B'
b=B()
print('%s'%b)
print('%r'%b)

item系列
__ getitem__ __ setitem__ __ delitem__

class Foo:
    def __init__(self,name):
        self.name=name
 
    def __getitem__(self,item):
        return  self.__dict__[item]
 
    def __setitem__(self, key, value):
        self.__dict__[key]=value
 
    def __delitem__(self, key):
        print('del obj[key]时,我执行')
        self.__dict__.pop(key)
 
f = Foo('alex')

f.name = …

print(f['name'])    # f.__getitem__('name')
f['age']  = 18      # 赋值
print(f.age)         # 自带的语法
print(f['age'])     # 修改
f['age']  = 80
print(f['age'])     # 通过实现__getitem__得到的
del f['age']
print(f.age)         # 删除

*** __ hash__***

class Foo:
    def __hash__(self):
        print('aaaaaaaaaa')
        return hash(self.name)
        # print('aaas')
f = Foo()
f.name = 'egon'
print(hash(f))  #hash方法是可以重写的

__hash__
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值