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.....
 
posted @ 2018-09-11 17:39  不停地走  阅读(1679)  评论(0编辑  收藏  举报