python 元类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # 将字符串作为执行目标,得到响应结果 # eval常用作类型转换:该函数执行完有返回值 dic_str = "{'a':1, 'b':2, 'c':3}" dic = eval (dic) # exec拥有执行更复杂的字符串:可以形成名称空间 class_str = ''' a = 10 b = 20 @classmethod def fn(cls): pass ''' local_dic = {} # 可以操作全局与局部两个名称空间,一般不用关心全局名称空间 exec (class_str, {}, local_dic) |
元类
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 元类:类的类 # 通过class产生的类,也是对象,而元类就是用来产生该对象的类 local_str = """ def __init__(self, name, age): self.name = name self.age = age def study(self): print(self.name + '在学习') """ local_dic = {} exec (local_str, {}, local_dic) Student = type ( 'Student' , (), l_d) print (Student) |
自定义元类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 控制类的产生过程,以及该类对象的产生过程 class MyMeta( type ): # 控制类的创建过程 def __init__( cls , class_name, bases, namespace): print ( cls , class_name, bases, namespace) super ().__init__(class_name, bases, namespace) def __call__( cls , * args, * * kwargs): obj = object .__new__( cls ) cls .__init__(obj, * args, * * kwargs) return obj # Student类与Student类的对象产生都可以备元类MyMeta控制 class Student(metaclass = MyMeta): def __init__( self , name, age): self .name = name self .age = age stu = Student( 'owen' , 18 ) print (stu.name) |
元类的应用
1 2 3 4 5 6 7 8 9 10 11 | class MyMeta( type ): def __call__( cls , * args, * * kwargs): if not hasattr ( cls , 'instance' ): cls .instance = cls .__new__( cls ) cls .instance.__init__( * args, * * kwargs) return cls .instance class A(metaclass = MyMeta): def __init__( self ): self .ip = '1.1.1.0' |
单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | class Song: __instance = None def __init__( self ): pass @classmethod def getInstance( cls ): if cls .__instance = = None : cls .__instance = cls () return cls .__instance s1 = Song.getInstance() s2 = Song.getInstance() print (s1, s2) def singleton( cls ): _instance = None def getInstance( * args, * * kwargs): nonlocal _instance if _instance = = None : _instance = cls ( * args, * * kwargs) return _instance return getInstance @singleton class A: def __init__( self , num): self .num = num print (A( 1 ), A( 2 ), A( 3 )) class A: __instance = None def __new__( cls , * args, * * kwargs): if cls .__instance = = None : cls .__instance = super ().__new__( cls ) return cls .__instance print (A(), A()) # single_module.py class Single: pass singleton = Single() # 测试文件 from single_module import singleton print (singleton) print (singleton) |
1.做项目,优先考虑要用到哪些对象:老师、学生、管理员、课程、学校等等,那就优先为这些对象创建出对应的类,而不是优先考虑项目要去实现哪些功能,功能的出发点永远从创建类开始,优先想到了该项目有哪些功能,也是重点向这些功能应该封装成什么类
2.类一旦有了,再思考,该类应该有哪些属性,这就是设计__init__方法的过程,然后思考该类有哪些方法,不需要对象的参与,就是类方法,需要就是对象方法
3.对于数据的存储,我们最终要持久化到文件或是硬盘,但是数据要在程序中使用,那就必须在内存中使用,那么数据在内存中采用哪种方式存储,列表可以,但是索引标识数据方式很不方便,字典可以,具有信息标识,对象也可以,具有信息标识,而且访问数据修改数据采用.语法,相当简单,所以优选对象存储,这也是面向对象的优点
4.那么随着项目的发展,很多类就仅仅用来存放数据的,那这样的类就可以称之为Model类,那这些类的数据也具备很多业务逻辑,那我们在面向对象思想中,不是将功能写在Model类中,而是定义处理业务的工具类,必然专门操作与数据库打交道的操作,丢在DB_Handle类中,那这样专门处理业务逻辑的类,我们称之为Ctrl类
5.而大型项目中有大量与用户交互的页面,我们也用专门的类来控制,这就是View类,就选课系统而言,可以封装打印各自信息的各种方法,也是在Ctrl的合适位置调用即可,这就是面向对象的 MVC 设计模式
标签:
python开发之路
· 字符集、编码的前世今生
· Web性能优化:从 2 秒到200毫秒
· WPF 使用GDI+提取图片主色调并生成Mica材质特效背景
· golang遍历处理map时的常见性能陷阱
· .NET8带来的一些新特性
· Web性能优化:从 2 秒到200毫秒
· 看到这种代码,我直接气到想打人
· Winform高级技巧-界面和代码分离的实践案例
· 1 分钟生成架构图?程序员 AI 绘图保姆级教程
· 字符集、编码的前世今生