• Python3中的单例模式 hasattr() getattr() serattr() delattr()


    #python中单例模式
    #1.使用__new__
    class Singleton:
        def __new__(cls,*args,**kwargs):
            if not hasattr(cls,'_instance'):
            cls._instance=super().__new__(cls)
            return cls._instance
                
    s0=Singleton()
    s1=Singleton()
    print(id(s0))
    print(id(s1))
    
    In [10]:
    #hasattr(object,name)函数用于判断是否包含对应的属性
    #参数:  object------对象           name------字符串,属性名
    #返回值: 如果对象有该属性返回True,否则返回False
    class People:
        country="china"
        def __init__(self,name):
            self.name=name
        def people_info(self):
            print("%s is xxx"%(self.name))
    obj=People('aaa')
    print(obj.name)
    print(hasattr(People,'country'))
    print(hasattr(obj,'name'))
    print(hasattr(People,'name'))
    print(hasattr(People,'people_info'))
    print(hasattr(obj,'people_info'))
    print(People.__dict__)
    print(obj.__dict__)
    
     
    aaa
    True
    True
    False
    True
    True
    {'__module__': '__main__', 'country': 'china', '__init__': <function People.__init__ at 0x0000024A642A7A60>, 'people_info': <function People.people_info at 0x0000024A642A78C8>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
    {'name': 'aaa'}
    
    In [14]:
    #2.使用装饰器
    from functools import wraps
    def singlenton(cls):
        instances={}
        
        @wraps(cls)
        def getinstance(*args,**kwargs):
            if cls not in instances:
                instances[cls]=cls(*args,**kwargs)
            return instances
        return getinstance
    @singlenton
    class Bar:
        pass
    
    b0=Bar()
    b1=Bar()
    print(id(b0))
    print(id(b1))
    
     
    2518531933456
    2518531933456
    
     

    装饰器的用法(小应用)

    def outer(func): def inner(): print("before func") ret=func() return ret+1 return inner #返回inner函数

    @outer #解释器执行 foo=outer(foo) def foo(): return 1

    print(foo) foo()

     

    这个过程中执行了下面几步

    1.函数 foo 作为 装饰器 outer 的参数被传入 2.函数 inner 对 func 进行调用,然后装饰器 outer 返回 inner 3.原来的函数名 foo 关联到 inner,如上面的foo 所示,调用 foo时间上是在调用 inner

    In [ ]:
    #装饰器的应用小例子
    #将对象作为函数的参数,去判断对象参数
    
    def wrapper(func):
        def checker(a,b):
            if a.x<0 or a.y <0:
                a=Coordinate(a.x  if a.x>0 else 0,a.y if a.y>0 else 0)
            if b.x<0 or b.y<0:
                b=Coordinate(b.x if b.x>0 else 0,b.y if b.y>0 else 0)
            ret=func(a,b)
            if ret.x<0 or ret.y<0:
                ret = Coordinate(ret.x if ret.x>0 else 0,re.y if ret.y>0 else 0)
            return ret
        return checker
    
        
    
    class Coordinate(object):
        def __init__(self,x,y):
            self.x=x
            self.y=y
        def __repr__(self):
            return "Coord:"+str(self.__dict__)
    @wrapper    
    def add(a,b):
        return Coordinate(a.x+b.x,a.y+b.y)
    @wrapper
    def sub(a,b):
        return Coordinate(a.x-b.x,a.y-b.y)
    one=Coordinate(100,200)
    two=Coordinate(300,400)
    three=Coordinate(-100,-100)
    sub(one,three)
    add(one,three)
    sub(one,two)
    # print(one)
    
        
    
    In [ ]:
    def hello(cls):
        cls.hello=staticmethod(lambda:"hello")
        return cls
    @hello
    class World(object):
        pass
    World.hello
    
    In [ ]:
    #使用元类,可以控制类的创建过程
    class Singleton(type):
        '''元类继承type'''
        _instance={}
        def __call__(cls,*args,**kwargs):
            if cls not in cls._instance:
                cls._instance[cls]=super().__call__(*args,**kwargs)
            return cls._instance
    class Bar(metaclass=Singleton):
        pass
    
    b0=Bar()
    b1=Bar()
    print(id(b0))
    print(id(b1))
                
    '''
    输出结果:
    2473667780824
    2473667780824
    '''

    #装饰器还可以为类增加额外的成员
    
    def hello(cls):
        cls.hello=staticmethod(lambda:"hello")
        return cls
    @hello
    class World(object):
        pass
    World.hello  #<function __main__.hello.<locals>.<lambda>()>
    World.hello()
    
    Out[3]:
    'hello'
    In [6]:
    #functools.wraps 则可以将原函数对象的指定属性复制给包装函数对象, 默认有 __module__、__name__、__doc__,或者通过参数选择
    from functools import wraps
    def logged(func):
        @wraps(func)
        def with_logging(*args,**kwargs):
            print(func.__name__+'was called')
            return func(*args,**kwargs)
        return with_logging
    @logged
    def f(x):
        '''does some math'''
        return x+x*x
    def f(x):
        '''does some math'''
        return x+x*x
    f=logged(f)
    f.__name__  #'f'
    f.__doc__
    
    Out[6]:
    'does some math'
    In [15]:
    def logged(func):
        def with_logging(*args,**kwargs):
            print(func.__name__+'was called')
            return func(*args,**kwargs)
        return with_logging
    @logged
    def f(x):
        '''does some math'''
        return x+x*x
    def f(x):
        '''does some math'''
        return x+x*x
    f=logged(f)
    f.__name__     #'with_logging'
    print(f.__doc__)
    
     
    None
    
    In [ ]:
    Python装饰器decorator在实现的时候被装饰后的函数其实已经是另外一个函数了函数名等函数属性会发生改变),
    为了不影响Python的functools包中提供了一个叫wraps的decorator来消除这样的副作用写一个decorator的时候最好在实现之前加上functools的wrap它能保留原有函数的名称和docstring
    In [17]:
    #使用元类,可以控制类的创建过程
    class Singleton(type):
        '''元类继承type'''
        _instance={}
        def __call__(cls,*args,**kwargs):
            if cls not in cls._instance:
                cls._instance[cls]=super().__call__(*args,**kwargs)
            return cls._instance
    class Bar(metaclass=Singleton):
        pass
    
    b0=Bar()
    b1=Bar()
    print(id(b0))
    print(id(b1))
                
    
     
    2473667780824
    2473667780824
    
    In [ ]:
    #getattr()函数
    #用于返回一个对象的属性值
    #getattr(object,name,default)
    '''
    参数 :
    object-----对象
    name------字符串,对象属性
    default ----默认返回值,如果不提供该参数,在没有对象属性时,将触发AttributeError
    返回值:
    放回对象属性值
    
    '''
    
    In [23]:
    class People:
        country='chaina'
        def __init__(self,name):
            self.name=name
        def people_info(self):
            print('%s is xxx'%(self.name))
            
    obj=getattr(People,'country')
    print(obj)
    '''
    obj1=getattr(People,'countryjjjjj')
    print(obj1)#没有属性的话,又没有默认属性参数的话,就会报错
    '''
    obj=getattr(People,'conutryjjjjj',None)
    print(obj)
    
     
    chaina
    None
    
    In [24]:
    #setattr()函数
    '''
    setattr函数,用于设置属性值,该属性必须存在
    语法:setattr(object,name,value)
    参数:
    object----对象
    name------字符串,对象属性
    value-----属性值
    返回值:
    '''
    
    class People:
        country='china'
        def __init__(self,name):
            self.name=name
        def people_info(self):
            print('%s is xxx'%(self.name))
            
    obj=People('aaa')
    setattr(People,'x',111)#等同于People.x=111
    print(People.x)
    print(obj.__dict__)
    print(People.__dict__)
    
     
    111
    {'name': 'aaa'}
    {'__module__': '__main__', 'country': 'china', '__init__': <function People.__init__ at 0x0000023FF21688C8>, 'people_info': <function People.people_info at 0x0000023FF21686A8>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None, 'x': 111}
    
    In [25]:
    #delattr()函数
    '''
    delattr函数用于删除属性
    delattr(x,'foobar')相当于del x.doobar
    语法:
    setattr(object,name)
    参数:
    object  ---对象
    name--必须是对象的属性
    返回值:
    '''
    
    class People:
          country='China'
          def __init__(self,name):
            self.name=name
          def people_info(self):
            print('%s is xxx' %(self.name))
        
    
    delattr(People,'country') #等同于del People.country
    print(People.__dict__)
    
     
    {'__module__': '__main__', '__init__': <function People.__init__ at 0x0000023FF2168D08>, 'people_info': <function People.people_info at 0x0000023FF2168AE8>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
    
    In [ ]:
    class Foo:
        def run(self):
            while True:
                cmd=input('cmd>>:'.strip())
                if hasattr(self,cmd):
                    func=getattr(self,cmd)
                    func()
        def download(self):
            print('download.....')
        def upload(self):
            print('upload...')
            
    obj=Foo()
    obj.run()
    
     
    cmd>>:download
    download.....
     
  • 相关阅读:
    EasyTransaction主要源码分析
    编程哲理小故事:Tina的运动会方阵
    多维扩展点的思考与设计——解决渠道、产品增加引发的腐化问题
    分布式事务框架Seata及EasyTransaction架构的比对思考
    设计,架构,框架之间是什么关系?
    你知道如何画好一幅架构图么?
    学会分享痛苦
    建立你自己的博客
    使用正确的工具软件
    掌握主动权
  • 原文地址:https://www.cnblogs.com/qingsheng/p/9629191.html
Copyright © 2020-2023  润新知