• Python基础之面向对象进阶


     一、isinstance(obj, cls) & issubclass(sub, super)

    isinstance(obj, cls)

     检查是否obj是否是类 cls 的对象

    1
    2
    3
    4
    5
    6
    class Foo(object):
        pass
      
    obj = Foo()
      
    isinstance(obj, Foo)

    issubclass(sub, super)

     检查sub类是否是 super 类的派生类

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

    二、反射

    python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

    # commons.py 文件
     
    name = "nick"
     
    def f1():
        return "This is f1."
     
    def f2():
        return "This is f2."
     
    def nb():
        return "This is niubily."
     
     
     
    # index.py 文件
    import commons
     
    #根据字符串的形式去某个模块中寻找东西
    target_func = getattr(commons,"f1")     # 找函数
    result = target_func()
    print(result)
     
    target_func = getattr(commons,"name")   # 找全局变量
    print(target_func)
     
    target_func = getattr(commons,"age",None)   # 找不到返回None
    print(target_func)
     
    #根据字符串的形式去某个模块中判断东西是否存在
    tarhas_func = hasattr(commons,"f5")     # 找函数
    print("before:",tarhas_func)
     
    # tarhas_func = hasattr(commons,"name") # 找全局变量
    # print(tarhas_func)
     
    #根据字符串的形式去某个模块中设置东西
    setattr(commons,"f5","lambda x: return "This is new func."")  # 设置一个函数
    setattr(commons,"age",18)       # 设置全局变量
     
    tarhas_func = hasattr(commons,"f5")     # 检查函数是否存在
    print("after:",tarhas_func)
     
    #根据字符串的形式去某个模块中删除东西
    delattr(commons,"f5")       # 删除一个函数
     
    tarhas_func = hasattr(commons,"f5")     # 检查函数是否存在
    print("end:",tarhas_func)
    # 通过字符串的形式,导入模块。起个别名 ccas。
    
    comm = input("Please:")
    ccas = __import__(comm)
    ccas.f1()
    
    # 需要做拼接导入时后加 fromlist=True(否则只导入lib)
    ccas = __import__("lib."+comm, fromlist=True)
    补充__import__
    ##### 路由系统 #####
    
    # 输入 模块名/函数名  (例如:commons/nb)
    url = input("Please input you want url:")
    
    target_module, target_func = url.split("/")
    
    #m = __import__("lib."+target_module,fromlist=True)
    m = __import__(target_module)
    
    if hasattr(m,target_func):
        target_func = getattr(m,target_func)
        result = target_func()
        print(result)
    else:
        print("Sorry,it's 404 not found.")
    
    路由系统
    路由系统

    三、类装饰器

    def deco(func):
        print('===================')
        return func  #fuc=test
    
    @deco    #test=deco(test)
    def test():
        print('test函数运行')
    test()
    框架
    def deco(obj):
        print('============',obj)
        obj.x=1   #增加属性
        obj.y=2
        obj.z=3
        return obj
    
    @deco   #Foo=deco(Foo)   #@deco语法糖的基本原理
    class Foo:
        pass
    
    print(Foo.__dict__)  #加到类的属性字典中
    
    输出
    ============ <class '__main__.Foo'>
    {'__module__': '__main__', 'z': 3, 'x': 1, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, 'y': 2}
    对类增加类属性
    def Typed(**kwargs):
        def deco(obj):
            for key,val in kwargs.items():
                setattr(obj,key,val)
            return obj
        return deco
    
    @Typed(x=1,y=2,z=3)  #typed(x=1,y=2,z=3)--->deco
    class Foo:
        pass
    print(Foo.__dict__)
    
    @Typed(name='egon')
    class Bar:
        pass
    print(Bar.name)
    
    控制台输出
    {'y': 2, '__dict__': <attribute '__dict__' of 'Foo' objects>, 'z': 3, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__module__': '__main__', 'x': 1, '__doc__': None}
    
    egon
    
    增强版
    多一例

    四、元类

    ython中一切皆是对象,类本身也是一个对象,当使用关键字class的时候,python解释器在加载class的时候就会创建一个对象(这里的对象指的是类而非类的实例)

    寻找类的父亲

    #type函数可以查看类型,也可以用来查看对象的类,二者是一样的
    print(type(f1)) # 输出:<class '__main__.Foo'>     表示,obj 对象由Foo类创建
    print(type(Foo)) # 输出:<type 'type'>  
    • 元类是类的类,是类的模板
    • 元类是用来控制如何创建类的,正如类是创建对象的模板一样
    • 元类的实例为类,正如类的实例为对象(f1对象是Foo类的一个实例Foo类是 type 类的一个实例)
    • type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象

    一个类没有声明自己的元类,默认它的元类就是type,除了使用元类type,用户也可以通过继承type来自定义元类(顺便我们也可以瞅一瞅元类如何控制类的创建,工作流程是什么)

    class Mytype(type):
        def __init__(self,a,b,c):
            print(self)
            print(a)
            print(b)
            print(c)
        def __call__(self, *args, **kwargs):
            print("call")
    
    class Slamdunk(metaclass=Mytype): # Mytype("Slamdunk",(object,),{}) 实际上就是这么做,但是传了4个参数
        # 声明Foo类由Mytype创建,声明自己的元类
        def __init__(self,name):
            self.name = name
    
    s1 = Slamdunk("樱木花道")
    # 根据python一切皆对象,Slamdunk() 本质上就是在触发创建 Slamdunk类的 元类的__call__
    
    控制台输出
    <class '__main__.Slamdunk'>  # 元类创建的实例(对象)
    Slamdunk # 实例名
    () # 继承的类,在python3中都默认继承object,即都为新式类
    {'__qualname__': 'Slamdunk', '__init__': <function Slamdunk.__init__ at 0x000002106AFBF840>, '__module__': '__main__'} # 实例类的属性字典
    call # 实例+() 触发了元类的__call__方法
    
    模拟初步认识
    View Code
    class Mytype(type):
        def __init__(self,a,b,c):
            print(self)
        def __call__(self, *args, **kwargs): # 传的值是怎么传进去的,就去怎么接收
            print("call")
            obj = object.__new__(self) # 生成一个实例
            self.__init__(obj,*args,**kwargs)   # 这里的self是Mytype产生的实例,这一步触发 Slamdunk 的构造方法
            return obj # __call__方法下的返回值是 self 产生的实例 赋值给s1
    class Slamdunk(metaclass=Mytype):
        #  Slamdunk = Mytype("Slamdunk",(object,),{}) 实际上就是这么做,但是传了4个参数
        # 声明Foo类由Mytype创建,声明自己的元类
        # 触发元类的__init__(元类的构造方法)
        def __init__(self,name):
            self.name = name
    s1 = Slamdunk("樱木花道")
    # 根据python一切皆对象,Slamdunk() 本质上就是在触发创建 Slamdunk类的 元类的__call__
    print(s1.__dict__) # 可以访问到实例对象的属性字典
    
    class Mytype(type):
        def __init__(self,a,b,c):
            print(self)
        def __call__(self, *args, **kwargs):
            obj = object.__new__(self)
            self.__init__(obj,*args,**kwargs) 
            return obj 
    class Slamdunk(metaclass=Mytype):
        def __init__(self,name):
            self.name = name
    s1 = Slamdunk("樱木花道")
    print(s1.__dict__) 
    
    控制台输出
    <class '__main__.Slamdunk'>
    {'name': '樱木花道'}
    
    # 可以加断点体验
    
    实现创建类的流程 精简版
    实现创建类的流程 精简版

    五、单例模式

       单例模式存在的目的是保证当前内存中仅存在单个实例

      (程序如果并发量大的话,内存里就会存在非常多功能上一模一样的对象。存在这些对象肯定会消耗内存,对于这些功能相同的对象可以在内存中仅创建一个,需要时都去调用)

    初级:

    # 单例模式
     
    class Foo:
     
        __n = None
     
        def __init__(self):
            self.name = "nick"
            self.age = 18
            self.job = "pythoner"
     
        @staticmethod
        def dl():
            if Foo.__n:
                return Foo.__n
            else:
                Foo.__n = Foo()
                return Foo.__n
     
     
    # 创建对象时不能再直接使用:obj = Foo(),而应该调用特殊的方法:obj = Foo.dl() 。
     
    f1 = Foo.dl()
    print(f1)
    f2 =Foo.dl()
    print(f2)
    f3 =Foo.dl()
    print(f3)
     
    # 运行结果
    <__main__.Foo object at 0x0000000001142390>
    <__main__.Foo object at 0x0000000001142390>
    <__main__.Foo object at 0x0000000001142390>
    View Code

    装饰器方式单例模式

    # 装饰器方式单例模式
     
    def singleton(argv):
        dic = {}
     
        def s(*args, **kwargs):
     
            if argv not in dic:
                dic[argv] = argv(*args, **kwargs)
                return dic[argv]
            else:
                return dic[argv]
     
        return s
     
     
    # 类上加单例装饰器
    @singleton
    class Foo:
        pass
     
    @singleton
    class Foo2:
        pass
    View Code

    升级:

    from abc import abstractmethod, ABCMeta
    
    class Singleton(object):
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls, "_instance"):
                cls._instance = super(Singleton, cls).__new__(cls)
            return cls._instance
    
    
    class MyClass(Singleton):
        def __init__(self, name=None):
            if name:
                self.name = name
    
    
    a = MyClass("a")
    
    print(a)
    print(a.name)
    
    b = MyClass('b')
    #
    print(b)
    print(b.name)
    #
    print(a)
    print(a.name)
  • 相关阅读:
    SSIS -->> Data Type
    SSIS ->> Parameter
    Data Flow ->> Term Lookup
    Data Flow ->> Term Extraction
    Data Flow ->> Pivot
    Data Flow ->> OLE Command
    Data Flow ->> Multicast
    Data Flow ->> Union All
    Data Flow ->> Merge
    LeetCode OJ 118. Pascal's Triangle
  • 原文地址:https://www.cnblogs.com/honglingjin/p/6200664.html
Copyright © 2020-2023  润新知