12月可以播种猥实吗?

小说:12月可以播种猥实吗?作者:乙徒平更新时间:2019-04-26字数:95276

关于元类,我写过一篇,如果你只是了解元类,看下面这一篇就足够了。

Python面向对象之类的方法和属性

本篇是深度解剖,如果你觉得元类用不到,呵呵,那是因为你不了解Django。

在Python中有一个type类,所有的类都是基于type类生成的,可谓万物之母。

如此广袤无垠的python生态圈,都是由type产生出来的。

Python面向对象总计包含五大部分:

常用部分:

3.class(类,或者叫实例生成器)

4.instance(实例)

5.实例的各种属性与方法,我们平常使用python时,调用的就是它们。

不常用部分(类从何而来):

1.type

2.metaclass(元类,或者叫类生成器)

 两种方式创建类:

# 创建一个Hello类,拥有属性say_hello
class Hello():
    def say_hello(self, name="gregory"):
        print( "Hello, %s."% name)
# 从Hello类创建一个实例hello
hello =Hello()
# 使用hello调用方法say_hello
hello.say_hello()

def func(self, name="gregory"):
# 创建函数func
    print("Hi, %s."% name)
Hi= type("Hi", (object,), dict(say_hello=func))
# 通过type创建Hi class
hello=Hi()
hello.say_hello()

效果一样的。

Hi= type("Hi", (object,), dict(say_hello=func))

第一个参数: 类名。我是谁。

第二个参数:当前类的基类。我从哪里来,也就是我的“父类”,以上实例中我的父类是“object”——python中一种非常初级的类。

第三个参数:类的成员。我要到哪里去,将需要调用的方法和属性包含到一个字典里,再作为参数传入。以上实例中,say_hello方法包装进了字典中。

type可以直接生成类(class),但也可以先生成元类(metaclass),再使用元类批量定制类(class)。

元类均被命名后缀为Metalass,元类的生命周期:

class SayMetaClass(type):
    #元类是由“type”衍生而出,所以父类需要传入type。
    def __new__(cls, name, bases, attrs):
        #元类的操作都在 __new__中完成,它的第一个参数是将创建的类,之后的参数即是三大永恒命题:类名,基类,类的成员。

        attrs["say_"+ name] =lambda self, value, saying=name:print(saying + ","+ value +"!")
        #创造属性和方法,由元类创建的类叫“Hello”,那创建时就自动有了一个叫“say_Hello”的类方法
        # 然后又将类的名字“Hello”作为默认参数saying,传到了方法里面。
        # 然后把hello方法调用时的传参作为value传进去,最终打印出来。

        return type.__new__(cls, name, bases, attrs)
        #传承类名,父类,属性

class Hello(object, metaclass =SayMetaClass):
    # 创建类,通过元类创建的类,第一个参数是父类,第二个参数是metaclass
    pass

hello =Hello()# 创建实列
hello.say_Hello( "gregory")# 调用实例方法

class Nihao(object,metaclass=SayMetaClass):
    pass

nihao=Nihao()
nihao.say_Nihao("greg 李")

应用:Django的核心思想是“Object Relational Mapping”,即对象-关系映射,简称ORM。

这是Django的一大难点,但学完了元类,一切变得清晰。你对Django的理解将更上一层楼!

通过元类创建ORM

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)

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

class IntegerField(Field):
    def __init__(self , name):
        super(IntegerField,self).__init__(name,"bigint")


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 mapping: %s ==> %s" % (k, v))
                mappings[k] = v
        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, **kwarg):
        super(Model, self).__init__(**kwarg)

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

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

    # 模拟建表操作
    def save(self):
        fields = []
        args = []
        for k, v in self.__mappings__.items():
            fields.append(v.name)
            args.append(getattr(self, k, None))
        sql = "insert into %s (%s) values (%s)" % (self.__table__, ",".join(fields), ",".join([str(i) for i in args]))
        print("SQL: %s" % sql)
        print("ARGS: %s" % str(args))


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

u = User(id=12345, name="Gregory", email="292409083@qq.com", password="iamgreg")
u.save()

这是Django中的Model版块核心原理!

运行结果:

Found model: User
Found mapping: id ==> <IntegerField:id>
Found mapping: name ==> <StringField:username>
Found mapping: email ==> <StringField:email>
Found mapping: password ==> <StringField:password>
SQL: insert into User(id,username,email,password) values (12345,Gregory,292409083@qq.com,iamgreg)
ARGS: [12345, "Gregory", "292409083@qq.com", "iamgreg"]

 

当前文章:http://www.cnsdbtzg.com/oc2gv.html

发布时间:2019-04-26 09:22:11

花石榴树一年开几次花? 全国水腊苗产地都有哪些? 红花碧桃哪里有,买优质观赏桃,来华东大型花木产区 购买玫瑰花苗要选对地方,选对供应商,选对品种 全网首发,苗圃实拍金叶水腊图片, 红叶小檗球是不是常绿的? 江西哪里有卖瓜子黄杨苗的? 哪里卖红刺梅? 紫藤哪种容易活? 江苏能种植常春藤苗吗?

69928 86907 97446 34981 11913 86545 60419 95163 70008 48812 54307 86523 32031 90547 99021 96521 76144 98706 73608 68477 71088 33620 33135

我要说两句: (0人参与)

发布