Python基础-使用type()和元类metaclass

type()函数

查看一个类型或变量的类型

type()函数可以查看一个类型或变量的类型

运行示例

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# type()函数可以查看一个类型或变量的类型

class Hello(object):

    def toString():
        print("helll world")

def runTest():
    mHello = Hello

    # type()函数可以查看一个类型或变量的类型
    result = type(mHello)
    print(result)

    result = type(mHello.toString)
    print(result)

runTest()

运行结果

D:\PythonProject\sustudy>python main.py
<class 'type'>
<class 'function'>

了解即可,个人觉得暂时没多少卵用

动态创建Class

示例代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# type() 的运行时动态创建

def functionDemo():
    print("Hello")

def runTest():

    # 动态创建Hello
    # 1. "Hello" 为class名称
    # 2. 继承的父类集合,主要这里是tuple包裹起来,有个逗号,不要看漏了
    # 3. class 的函数名与函数绑定
    Hello = type("Hello", (object,), dict(fun = functionDemo))
    Hello.fun()


runTest()

运行结果

D:\PythonProject\sustudy>python main.py
Hello

Python面向对象里最难理解 metaclass

metaclass,直译为元类,运行时动态控制类的创建行为

我们定义了类以后,就可以根据这个类创建出实例,所以:先定义类,然后创建实例。

但是如果我们想创建出类呢?那就必须根据metaclass创建出类,所以:先定义metaclass,然后创建类。

连接起来就是:先定义metaclass,就可以创建类,最后创建实例。

所以,metaclass允许你创建类或者修改类。换句话说,你可以把类看成是metaclass创建出来的“实例”。

metaclass是Python面向对象里最难理解,也是最难使用的魔术代码。正常情况下,你不会碰到需要使用metaclass的情况,所以,以下内容看不懂也没关系,因为基本上你不会用到。

List新增add的方法

示例

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 元类 metaclass

# Demo list新增add的方法

# metaclass 是类的模板,故继承type
class ListMetaclass(type):

    # cls 当前准备创建的类的对象
    # name 类的名字
    # bases 类继承的父类集合
    # attrs 类的方法集合
    def __new__(cls, name, bases, attrs):
        # lambda 匿名函数,这里新增add方法用
        attrs["add"] = lambda self, value: self.append(value)
        return type.__new__(cls, name, bases, attrs)

class MyList(list, metaclass = ListMetaclass):
    pass

def runTest():
    mList = MyList()
    mList.add(1)
    print(mList)

runTest()

运行结果

D:\PythonProject\sustudy>python main.py
[1]

ORM框架

ORM全称“Object Relational Mapping”,即对象-关系映射,就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表,这样,写代码更简单,不用直接操作SQL语句。

示例

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ORM框架

#================================================================
# Field类
# 负责保存数据库表的字段名和字段类型
class Field(object):

    def __init__(self, name, column_type):
        self.name = name
        self.column_type = column_type

    # 让打印更好看些
    def __str__(self):
        return "<%s : %s>"%(self.__class__.__name__, self.name);

# IntegerField类型
class StringField(Field):

    def __init__(self, name):
        super(StringField, self).__init__(name, "varchar(varchar(100))")

# IntegerField类型
class IntegerField(Field):

    def __init__(self, name):
        super(IntegerField, self).__init__(name, "bigint")
#================================================================
# ModelMetaclass
# metaclass是Python中非常具有魔术性的对象,它可以改变类创建时的行为。这种强大的功能使用起来务必小心。
class ModelMetaclass(type):

    def __new__(cls, name, bases, attrs):
        if name == "Model":
            return type.__new__(cls, name, bases, attrs)

        print("Found model %s" % name)

        mappings = dict()
        for k, v in attrs.items():
            if isinstance(v, Field):
                print("Found mappings %s -> %s" % (k, v))
                mappings[k] = v

        # 排除掉对Modle的修改
        for k in mappings.keys():
            attrs.pop(k)

        # 保存属性和列的映射关系
        attrs["__mappings__"] = mappings
        # 假设表名和类名一致
        attrs["__table__"] = name

        return type.__new__(cls, name, bases, attrs)

#================================================================
# 基类
class Model(dict, metaclass=ModelMetaclass):

    def __init__(self, **kw):
        super(Model, self).__init__(**kw)

    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(r"'Model' object has no attribute '%s'" % key)

    def __setattr__(self, key, value):
        self[key] = value

    def save(self):
        fields = []
        params = []
        args = []
        for k, v in self.__mappings__.items():
            fields.append(v.name)
            params.append('?')
            args.append(getattr(self, k, None))
        sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(params))
        print('SQL: %s' % sql)
        print('ARGS: %s' % str(args))

#================================================================
# User 调用接口
class User(Model):
    # 定义类的属性到列的映射
    id = IntegerField("id")
    name = StringField("username")

# 创建一个实例
u = User(id = 1, name = "法迪")
# 保存到数据库
u.save()        

运行结果

D:\PythonProject\sustudy>python main.py
Found model User
Found mappings id -> <IntegerField : id>
Found mappings name -> <StringField : username>
SQL: insert into User (id,username) values (?,?)
ARGS: [1, '法迪']

上述了解即可,真正用到再详细理解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

法迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值