python 元类

eval与exec内置方法

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 设计模式

 

 

posted @   zack赵康  阅读(240)  评论(0)    收藏  举报
(评论功能已被禁用)
编辑推荐:
· 字符集、编码的前世今生
· Web性能优化:从 2 秒到200毫秒
· WPF 使用GDI+提取图片主色调并生成Mica材质特效背景
· golang遍历处理map时的常见性能陷阱
· .NET8带来的一些新特性
阅读排行:
· Web性能优化:从 2 秒到200毫秒
· 看到这种代码,我直接气到想打人
· Winform高级技巧-界面和代码分离的实践案例
· 1 分钟生成架构图?程序员 AI 绘图保姆级教程
· 字符集、编码的前世今生
点击右上角即可分享
微信分享提示