Python基础之面向对象进阶

快来打我* 2022-01-05 10:34 458阅读 0赞

一、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,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

  1. # commons.py 文件
  2. name = "nick"
  3. def f1():
  4. return "This is f1."
  5. def f2():
  6. return "This is f2."
  7. def nb():
  8. return "This is niubily."
  9. # index.py 文件
  10. import commons
  11. #根据字符串的形式去某个模块中寻找东西
  12. target_func = getattr(commons,"f1") # 找函数
  13. result = target_func()
  14. print(result)
  15. target_func = getattr(commons,"name") # 找全局变量
  16. print(target_func)
  17. target_func = getattr(commons,"age",None) # 找不到返回None
  18. print(target_func)
  19. #根据字符串的形式去某个模块中判断东西是否存在
  20. tarhas_func = hasattr(commons,"f5") # 找函数
  21. print("before:",tarhas_func)
  22. # tarhas_func = hasattr(commons,"name") # 找全局变量
  23. # print(tarhas_func)
  24. #根据字符串的形式去某个模块中设置东西
  25. setattr(commons,"f5","lambda x: return \"This is new func.\"") # 设置一个函数
  26. setattr(commons,"age",18) # 设置全局变量
  27. tarhas_func = hasattr(commons,"f5") # 检查函数是否存在
  28. print("after:",tarhas_func)
  29. #根据字符串的形式去某个模块中删除东西
  30. delattr(commons,"f5") # 删除一个函数
  31. tarhas_func = hasattr(commons,"f5") # 检查函数是否存在
  32. print("end:",tarhas_func)

ContractedBlock.gif ExpandedBlockStart.gif

  1. # 通过字符串的形式,导入模块。起个别名 ccas。
  2. comm = input("Please:")
  3. ccas = __import__(comm)
  4. ccas.f1()
  5. # 需要做拼接导入时后加 fromlist=True(否则只导入lib)
  6. ccas = __import__("lib."+comm, fromlist=True)

补充__import__

ContractedBlock.gif ExpandedBlockStart.gif

  1. ##### 路由系统 #####
  2. # 输入 模块名/函数名 (例如:commons/nb)
  3. url = input("Please input you want url:")
  4. target_module, target_func = url.split("/")
  5. #m = __import__("lib."+target_module,fromlist=True)
  6. m = __import__(target_module)
  7. if hasattr(m,target_func):
  8. target_func = getattr(m,target_func)
  9. result = target_func()
  10. print(result)
  11. else:
  12. print("Sorry,it's 404 not found.")
  13. 路由系统

路由系统

三、类装饰器

ContractedBlock.gif ExpandedBlockStart.gif

  1. def deco(func):
  2. print('===================')
  3. return func #fuc=test
  4. @deco #test=deco(test)
  5. def test():
  6. print('test函数运行')
  7. test()

框架

ContractedBlock.gif ExpandedBlockStart.gif

  1. def deco(obj):
  2. print('============',obj)
  3. obj.x=1 #增加属性
  4. obj.y=2
  5. obj.z=3
  6. return obj
  7. @deco #Foo=deco(Foo) #@deco语法糖的基本原理
  8. class Foo:
  9. pass
  10. print(Foo.__dict__) #加到类的属性字典中
  11. 输出
  12. ============ <class '__main__.Foo'>
  13. {
  14. '__module__': '__main__', 'z': 3, 'x': 1, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, 'y': 2}

对类增加类属性

ContractedBlock.gif ExpandedBlockStart.gif

  1. def Typed(**kwargs):
  2. def deco(obj):
  3. for key,val in kwargs.items():
  4. setattr(obj,key,val)
  5. return obj
  6. return deco
  7. @Typed(x=1,y=2,z=3) #typed(x=1,y=2,z=3)--->deco
  8. class Foo:
  9. pass
  10. print(Foo.__dict__)
  11. @Typed(name='egon')
  12. class Bar:
  13. pass
  14. print(Bar.name)
  15. 控制台输出
  16. {
  17. 'y': 2, '__dict__': <attribute '__dict__' of 'Foo' objects>, 'z': 3, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__module__': '__main__', 'x': 1, '__doc__': None}
  18. egon
  19. 增强版

多一例

四、元类

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

寻找类的父亲

  1. #type函数可以查看类型,也可以用来查看对象的类,二者是一样的
  2. print(type(f1)) # 输出:<class '__main__.Foo'> 表示,obj 对象由Foo类创建
  3. print(type(Foo)) # 输出:<type 'type'>
  • 元类是类的类,是类的模板
  • 元类是用来控制如何创建类的,正如类是创建对象的模板一样
  • 元类的实例为类,正如类的实例为对象(f1对象是Foo类的一个实例Foo类是 type 类的一个实例)

  • type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象

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

ContractedBlock.gif ExpandedBlockStart.gif

  1. class Mytype(type):
  2. def __init__(self,a,b,c):
  3. print(self)
  4. print(a)
  5. print(b)
  6. print(c)
  7. def __call__(self, *args, **kwargs):
  8. print("call")
  9. class Slamdunk(metaclass=Mytype): # Mytype("Slamdunk",(object,),{}) 实际上就是这么做,但是传了4个参数
  10. # 声明Foo类由Mytype创建,声明自己的元类
  11. def __init__(self,name):
  12. self.name = name
  13. s1 = Slamdunk("樱木花道")
  14. # 根据python一切皆对象,Slamdunk() 本质上就是在触发创建 Slamdunk类的 元类的__call__
  15. 控制台输出
  16. <class '__main__.Slamdunk'> # 元类创建的实例(对象)
  17. Slamdunk # 实例名
  18. () # 继承的类,在python3中都默认继承object,即都为新式类
  19. {
  20. '__qualname__': 'Slamdunk', '__init__': <function Slamdunk.__init__ at 0x000002106AFBF840>, '__module__': '__main__'} # 实例类的属性字典
  21. call # 实例+() 触发了元类的__call__方法
  22. 模拟初步认识
  23. class Mytype(type):
  24. def __init__(self,a,b,c):
  25. print(self)
  26. def __call__(self, *args, **kwargs): # 传的值是怎么传进去的,就去怎么接收
  27. print("call")
  28. obj = object.__new__(self) # 生成一个实例
  29. self.__init__(obj,*args,**kwargs) # 这里的self是Mytype产生的实例,这一步触发 Slamdunk 的构造方法
  30. return obj # __call__方法下的返回值是 self 产生的实例 赋值给s1
  31. class Slamdunk(metaclass=Mytype):
  32. # Slamdunk = Mytype("Slamdunk",(object,),{}) 实际上就是这么做,但是传了4个参数
  33. # 声明Foo类由Mytype创建,声明自己的元类
  34. # 触发元类的__init__(元类的构造方法)
  35. def __init__(self,name):
  36. self.name = name
  37. s1 = Slamdunk("樱木花道")
  38. # 根据python一切皆对象,Slamdunk() 本质上就是在触发创建 Slamdunk类的 元类的__call__
  39. print(s1.__dict__) # 可以访问到实例对象的属性字典

ContractedBlock.gif ExpandedBlockStart.gif

  1. class Mytype(type):
  2. def __init__(self,a,b,c):
  3. print(self)
  4. def __call__(self, *args, **kwargs):
  5. obj = object.__new__(self)
  6. self.__init__(obj,*args,**kwargs)
  7. return obj
  8. class Slamdunk(metaclass=Mytype):
  9. def __init__(self,name):
  10. self.name = name
  11. s1 = Slamdunk("樱木花道")
  12. print(s1.__dict__)
  13. 控制台输出
  14. <class '__main__.Slamdunk'>
  15. {
  16. 'name': '樱木花道'}
  17. # 可以加断点体验
  18. 实现创建类的流程 精简版

实现创建类的流程 精简版

五、单例模式

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

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

初级:

ContractedBlock.gif ExpandedBlockStart.gif

  1. # 单例模式
  2. class Foo:
  3. __n = None
  4. def __init__(self):
  5. self.name = "nick"
  6. self.age = 18
  7. self.job = "pythoner"
  8. @staticmethod
  9. def dl():
  10. if Foo.__n:
  11. return Foo.__n
  12. else:
  13. Foo.__n = Foo()
  14. return Foo.__n
  15. # 创建对象时不能再直接使用:obj = Foo(),而应该调用特殊的方法:obj = Foo.dl() 。
  16. f1 = Foo.dl()
  17. print(f1)
  18. f2 =Foo.dl()
  19. print(f2)
  20. f3 =Foo.dl()
  21. print(f3)
  22. # 运行结果
  23. <__main__.Foo object at 0x0000000001142390>
  24. <__main__.Foo object at 0x0000000001142390>
  25. <__main__.Foo object at 0x0000000001142390>

装饰器方式单例模式

ContractedBlock.gif ExpandedBlockStart.gif

  1. # 装饰器方式单例模式
  2. def singleton(argv):
  3. dic = {}
  4. def s(*args, **kwargs):
  5. if argv not in dic:
  6. dic[argv] = argv(*args, **kwargs)
  7. return dic[argv]
  8. else:
  9. return dic[argv]
  10. return s
  11. # 类上加单例装饰器
  12. @singleton
  13. class Foo:
  14. pass
  15. @singleton
  16. class Foo2:
  17. pass

升级:

  1. from abc import abstractmethod, ABCMeta
  2. class Singleton(object):
  3. def __new__(cls, *args, **kwargs):
  4. if not hasattr(cls, "_instance"):
  5. cls._instance = super(Singleton, cls).__new__(cls)
  6. return cls._instance
  7. class MyClass(Singleton):
  8. def __init__(self, name=None):
  9. if name:
  10. self.name = name
  11. a = MyClass("a")
  12. print(a)
  13. print(a.name)
  14. b = MyClass('b')
  15. #
  16. print(b)
  17. print(b.name)
  18. #
  19. print(a)
  20. print(a.name)

转载于:https://www.cnblogs.com/honglingjin/p/6200664.html

发表评论

表情:
评论列表 (有 0 条评论,458人围观)

还没有评论,来说两句吧...

相关阅读