zoukankan      html  css  js  c++  java
  • 内置函数、反射、__str__、__del__、元类

    一、内置函数的补充

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

    class Foo:
        pass
    
    obj=Foo()
    print(isinstance(obj,Foo)) # 推荐使用该函数来判断一个函数的类型,判断obj(对象)是否是Foo(类)的对象,是则为真,否则为假
    
    也可用下面main方法判断
    print(type(obj) is Foo)


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

     class Foo(object):
    2     pass
    3  
    4 class Bar(Foo):
    5     pass
    6  
    7 issubclass(Bar, Foo)
    

    二、反射

     #下述四个函数是专门用来操作类与对象属性的,如何操作?

    #通过字符串来操作类与对象的属性,这种操作称为反射
    class People:
        country="China"
        def __init__(self,name):
            self.name=name
        def tell(self):
            print('%s is aaa' %self.name)
    
    obj=People('egon')
    
    # 1、hasattr            #判断object中有没有一个name字符串对应的方法或属性
    # print(hasattr(People,'country'))       #判断类中有没有一个 'country' 字符串对应的方法或属性
    # print('country' in People.__dict__)       #判断country是否在类的字典中
    # print(People.__dict__)                #拿到类的字典
    # print(hasattr(obj,'name'))
    # print(hasattr(obj,'country'))           #判断obj(对象)有没有一个 'country' 字符串对应的方法或属性
    # print(hasattr(obj,'tell'))
    
    # 2、getattr
    # x=getattr(People,'country')             #获取类中country的属性是China
    # x=getattr(People,'country1',None)          #获取country1的属性,没有则返回None
    # print(x)
    
    # f=getattr(obj,'tell',None)#obj.tell          #获取obj(对象)中tell的函数属性,没有则返回None
    # print(f == obj.tell)          #True
    # f()
    # obj.tell()                   #与f()调用结果相等
    
    
    # 3、setattr              #设置属性
    # People.x=111
    # setattr(People,'x',111)
    # print(People.x)
    
    # obj.age=18
    # setattr(obj,"age",18)
    # print(obj.__dict__)
    
    # 4、delattr               #删除属性
    # del People.country
    # delattr(People,"country")
    # print(People.__dict__)
    
    # del obj.name
    # delattr(obj,"name")
    # print(obj.__dict__)
    
    
    
    
    
    class Foo:
        def run(self):
            while True:
                cmd=input('cmd>>: ').strip()
                # print('%s run...' %cmd)
                if hasattr(self,cmd):            #查看属性,用户输入的字符串是download或upload程序才会获得该属性,否则重复循环输入
                    func=getattr(self,cmd)         #获取属性
                    func()
    
        def download(self):
            print('download....')
    
        def upload(self):
            print('upload...')
    
    obj=Foo()
    obj.run()

    三、__str__ 方法

    class People:
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
    
        def __str__(self):             #改变对象的字符串显示,如果要把一个类的实例变成 str,就需要实现特殊方法__str__():
            # print('========>')           #__str__()用于显示给用户
            return '<名字:%s 年龄:%s 性别:%s>' %(self.name,self.age,self.sex)
    
    obj=People('egon',18,'male')
    print(obj) #print(obj.__str__())
    
    # l=list([1,2,3])
    # print(l)

    四、__del__ 方法

     import time
    #
    # class People:
    #     def __init__(self,name,age,sex):
    #         self.name=name
    #         self.age=age
    #         self.sex=sex
    #
    #     def __del__(self): # 在对象被删除的条件下,自动执行,没有被删除时不会执行
    #         print('__del__')
    #
    #
    # obj=People('egon',18,'male')
    # time.sleep(5)                  #通过延迟后删除属性,可以看到__del__,才会自动执行
    # del obj #obj.__del__()
    
    
    
    
    
    
    # class Mysql:
    #     def __init__(self,ip,port):
    #         self.ip=ip
    #         self.port=port
    #         self.conn=connect(ip,port) # 申请系统资源
    #
    #     def __del__(self):            #
    #         self.conn.close()
    #
    # obj=Mysql('1.1.1.1',3306)
    
    
    class MyOpen:
        def __init__(self,filepath,mode="r",encoding="utf-8"):
            self.filepath=filepath
            self.mode=mode
            self.encoding=encoding
            self.fobj=open(filepath,mode=mode,encoding=encoding)
    
        def __str__(self):      #定义一个字符串并将其值返回
            msg="""
            filepath:%s
            mode:%s
            encoding:%s
            """ %(self.filepath,self.mode,self.encoding)
            return msg
    
        def __del__(self):
            self.fobj.close()
    
    f=open('a.txt',mode='r',encoding='utf-8')
    
    f=MyOpen('aaa.py',mode='r',encoding='utf-8')
    print(f.filepath,f.mode,f.encoding)
    print(f)
    
    print(f.fobj)
    res=f.fobj.read()
    print(res)

    五、元类

    定义:

    元类:类的类就是元类
     code="""
    # global x
    # x=0
    # y=2
    # """
    # global_dic={'x':100000}
    # local_dic={}
    # exec(code,global_dic,local_dic)
    #
    # print(global_dic)
    # print(local_dic)
    
    #
    # code="""
    # x=1
    # y=2
    # def f1(self,a,b):
    #     pass
    # """
    # local_dic={}
    # exec(code,{},local_dic)
    # print(local_dic)
    #
    
    
    
    #1、一切皆为对象:
    
    # Chinese=type(...)
    # class Chinese:
    #     country="China"
    #
    #     def __init__(self,name,age,sex):
    #         self.name=name
    #         self.age=age
    #         self.sex=sex
    #
    #     def speak(self):
    #         print('%s speak Chinese' %self.name)
    #
    # print(Chinese)
    # p=Chinese('egon',18,'male')
    # print(type(p))
    
    # print(type(Chinese))
    # 元类:类的类就是元类,
    #我们用class定义的类使用来产生我们自己的对象的
    #内置元类type是用来专门产生class定义的类的
    
    class Foo: #Foo=type(...)
        pass
    
    # print(type(Foo))
    # f=Foo
    #
    # l=[Foo,]
    # print(l)
    
    #2、用内置的元类type,来实例化得到我们的类
    # class_name='Chinese'
    # class_bases=(object,)
    # class_body="""
    # country="China"
    # def __init__(self,name,age,sex):
    #     self.name=name
    #     self.age=age
    #     self.sex=sex
    # def speak(self):
    #     print('%s speak Chinese' %self.name)
    # """
    # class_dic={}
    # exec(class_body,{},class_dic)
    
    # 类的三大要素
    # print(class_name,class_bases,class_dic)
    
    # Chinese=type(class_name,class_bases,class_dic)
    # print(Chinese)
    
    # p=Chinese('egon',18,'male')
    # print(p.name,p.age,p.sex)
    
    
    #3、储备知识__call__
    # class Foo:
    #     def __init__(self):
    #         pass
    #     def __str__(self):
    #         return '123123'
    #
    #     def __del__(self):
    #         pass
    #
    #     # 调用对象,则会自动触发对象下的绑定方法__call__的执行,
    #     # 然后将对象本身当作第一个参数传给self,将调用对象时括号内的值
    #     #传给*args与**kwargs
    #     def __call__(self, *args, **kwargs):
    #         print('__call__',args,kwargs)
    #
    #
    # obj=Foo()
    # # print(obj)
    #
    # obj(1,2,3,a=1,b=2,c=3) #
    
    
    # #4 、自定义元类:
    # class Mymeta(type):
    #     # 来控制类Foo的创建
    #     def __init__(self,class_name,class_bases,class_dic): #self=Foo
    #         # print(class_name)
    #         # print(class_bases)
    #         # print(class_dic)
    #         if not class_name.istitle():
    #             raise TypeError('类名的首字母必须大写傻叉')
    #
    #         if not class_dic.get('__doc__'):
    #             raise TypeError('类中必须写好文档注释,大傻叉')
    #
    #         super(Mymeta,self).__init__(class_name,class_bases,class_dic)
    #
    #     # 控制类Foo的调用过程,即控制实例化Foo的过程
    #     def __call__(self, *args, **kwargs): #self=Foo,args=(1111,) kwargs={}
    #         # print(self)
    #         # print(args)
    #         # print(kwargs)
    #
    #         #1 造一个空对象obj
    #         obj=object.__new__(self)
    #
    #         #2、调用Foo.__init__,将obj连同调用Foo括号内的参数一同传给__init__
    #         self.__init__(obj,*args,**kwargs)
    #
    #         return obj
    #
    #
    #
    # #Foo=Mymeta('Foo',(object,),class_dic)
    # class Foo(object,metaclass=Mymeta):
    #     """
    #     文档注释
    #     """
    #     x=1
    #     def __init__(self,y):
    #         self.Y=y
    #
    #     def f1(self):
    #         print('from f1')
    #
    #
    # obj=Foo(1111) #Foo.__call__()
    #
    # # print(obj)
    # # print(obj.y)
    # # print(obj.f1)
    # # print(obj.x)
    
    
    
    
    
    # 单例模式
    import settings
    
    class MySQL:
        __instance=None
        def __init__(self,ip,port):
            self.ip=ip
            self.port=port
    
        @classmethod
        def singleton(cls):
            if not cls.__instance:
                obj=cls(settings.IP, settings.PORT)
                cls.__instance=obj
            return cls.__instance
    
    obj1=MySQL('1.1.1.2',3306)
    obj2=MySQL('1.1.1.3',3307)
    obj3=MySQL('1.1.1.4',3308)
    
    # obj4=MySQL(settings.IP,settings.PORT)
    # print(obj4.ip,obj4.port)
    
    obj4=MySQL.singleton()
    obj5=MySQL.singleton()
    obj6=MySQL.singleton()
    
    print(obj4 is obj5 is obj6)
    

      

    
    
  • 相关阅读:
    CF980E The Number Games
    UVALive 2995 Image Is Everything
    CF1148F Foo Fighters
    CF22E Scheme
    CF1045G AI robots
    学习笔记 并查集维护区间删除
    HEOI 十二省联考退役记
    立方网面试题总结
    Django学习排错备注
    追求卓越之旅(转)
  • 原文地址:https://www.cnblogs.com/sui776265233/p/8868222.html
Copyright © 2011-2022 走看看