25-1 面向对象(反射、单例模式)
一、反射
通过字符串的形式操作(增/删/改/查)对象中成员。由hasattr()、getattr()、setattr()、delattr()四个内置函数实现。
问题的引入
class Foo(object):
def __init__(self):
self.name = 'alex'
def func(self):
return 'func'
obj = Foo()
obj.name # 访问字段
obj.func() # 执行方法
# n = 'name'
# obj.n # 这种写法是错误的,obj.后面的 n和前面的 n='name'没任何关系
上述访问对象成员的 name 和 func 是什么?是变量名。obj.xxx 表示去obj中或类中寻找变量名 xxx,并获取对应内存地址中的内容。
那怎么用字符串‘name’去拿到name的值呢?
两种方法:
obj.__dict__['name']
getattr(obj, 'name')
第二种方式即反射。
1. 常规对象
class Foo(object):
def __init__(self):
self.name = 'wupeiqi'
def func(self):
return 'func'
obj = Foo()
# #### 检查是否含有成员 ####
hasattr(obj, 'name') # 有则返回 True,无 False
hasattr(obj, 'func')
# #### 获取成员 ####
getattr(obj, 'name') # 等价于 obj.name
getattr(obj, 'func')
# #### 设置成员 ####
setattr(obj, 'age', 18)
setattr(obj, 'show', lambda num: num + 1)
# #### 删除成员 ####
delattr(obj, 'name')
delattr(obj, 'func')
2. 类也是对象
class Foo(object):
name = 'alex'
def func(self):
return 'func'
getattr(Foo, 'name') # 等价于 Foo.name。一切皆对象
3. 模块也是对象
#以下为 s1.py文件的内容
def p1():
print("首页")
def p2():
print("新闻")
def p3():
print("精华")
# 以下为s2.py文件的内容
import s1
inp = input(">>:") # 用户可选择输入p1、p2、p3其中一个
func = getattr(s1, inp) # 到 s1对象中取
func()
二、设计模式
一、单例模式
单例,顾名思义单个实例。
创建对象的过程就是将类实例化的过程,对象又叫实例。
class Foo:
__v = None
@classmethod
def get_instance(cls):
if cls.__v:
return cls.__v
else:
cls.__v = Foo()
return cls.__v
obj1 = Foo.get_instance()
obj2 = Foo.get_instance()
obj3 = Foo.get_instance()
print(obj1) # <__main__.Foo object at 0x00000000028AB828>
print(obj2) # <__main__.Foo object at 0x00000000028AB828>
print(obj3) # <__main__.Foo object at 0x00000000028AB828>
单利模式存在的目的是保证当前内存中仅存在单个实例,避免内存浪费!!!
应用场景:如数据库连接池
浙公网安备 33010602011771号