澳门新蒲京娱乐

新蒲京官方下载 4
python首要知识点总结一新蒲京官方下载:,python自带的四个装饰器

内建函数getattr工厂模式新蒲京官方下载:,多进程并发机制

Django的models达成分析

python元类:**type()   **

 

元类是python高阶语法.
合理的接纳能够减小大气重复性的代码.

1      引子

 

1.1     神奇的Django中的models

作者们先来看一段在Django项目中常用的代码:

安装数据库models代码:

class Students(models.Model):
    name = models.CharField()
    age = models.IntegerField()

此地有多少个神奇的地点,涉及到了python中最隐私的多少个特色。

先看下有如何神奇的地方:

  • 字段名称name\age自动转换为了数据库中的字段名称
  • 自动校验数据类型,models.Integer菲尔德(),会校验设置的数据类型

此处用的是python的五个语法本性:

  • 讲述符协议
  • 元类

咱俩来一步一步解开神秘面纱。

元类实际上做了以下三上面的劳作:

2      数据校验

 

2.1     数据校验难题

Python就算是强类型的脚本语言,然则在概念变量时却无力回天内定变量的类型。

譬如,大家在Student类中定义1个age字段,合法值一般为包括0的正整数,可是在python中无正整数的花色,只可以自个儿来校验。

class Student:
    def __init__(self, name, age):
        if isinstance(name,str):
            self.name = name
        else:
            raise TypeError("Must be a string")

        if isinstance(int, age):
            self.age = age
        else:
            raise TypeError("Must be an int")

 

而是,如果更新岁龄时就会遇见标题,不能重用校验逻辑。

有没有简要的办法吧?

  • 干预创制类的经过
  • 修改类
  • 回到修改之后的类

2.2     使用property装饰器

运用property也是多少个方法,能够本着各样属性来设置,然则只要一个类有五个性情,代码就会要命的多,并且产生多量的冗余,仿佛那样。

新蒲京官方下载 1新蒲京官方下载 2

class Student:
    def __init__(self, name, age, class_no, address, phone):
        self._name = None
        self._age = None
        self.__class_no = None
        self._address = None
        self._phone = None

        self.name = name
        self.age = age
        self.class_no = class_no
        self.address = address
        self.phone = phone

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        if not isinstance(value, str):
            raise ValueError("Must be string")
        self._name = value

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, value):
        if isinstance(value, int) and value > 0:
            self._age = value
        else:
            raise ValueError("age value error")

    @property
    def address(self):
        return self._address

    @address.setter
    def address(self, value):
        if not isinstance(value, str):
            raise ValueError("Must be string")
        self._address = value

View Code

 

代码冗余太多,各样检查str的都要复制二回代码。

 

3      Python描述符

叙述符提供了优雅、简洁、健壮和可选择的缓解方案。简单的讲,三个叙述符正是2个指标,该指标表示了壹脾性格的值。

那就象征一旦二个Student对象有叁天特性“name”,那么描述符正是另叁个可以用来代表属性“name”持有值的目的。

叙述符协议中“定义了__get__”、“__set__”或”__delete__”
那一个特殊措施,描述符是达成个中二个或八个法子的目的。

何以接纳元类?

 

缘何要选拔元类那种歪曲且易于失误的成效?
貌似景况下,大家并不会利用元类,99%的开发者并不会用到元类,所以一般不要考虑那么些难题。
元类主用用于创立API,1个卓越的例证正是Django的OXC60M。
它让大家得以如此定义二个类:

新蒲京官方下载 , 

class Person(models.Model):
  name = models.CharField(max_length=30)
  age = models.IntegerField()

 

运维下边包车型客车代码:

guy = Person(name='bob', age='35')
print(guy.age)

回来的结果是int品种而不是IntegerField对象。那是因为models.Model动用了元类,它会将Python中定义的字段转换来数据库中的字段。
透过利用元类,Django将复杂的接口转换来简单的接口。

 

原型:type(类名,基类元组(可以为空,用于继承), 包含属性或函数的字典)

 以下二种写法都能够:

type(‘Class’,(object,),dict(hello=fun()))

type(‘Class’,(object,),{“hello”:fun()})

壹 、class 自定义的类名称

二 、(object,)是继承类,的元组,要是唯有一个就写那种时局(object,);多个(object,xxxx,)

三 、dict(hello=fun()) 或 {“hello”:fun()}
第一个参数,是2个字典等号左是
自定义的点子名,右边是已写好的点子名,这些要专注,有参数且没有私下认可值的景况下,要加括号;

 

def fun():
    print('hello world!')


if __name__=="__main__":

    h = type('Hello',(object,),dict(hello=fun()))
    tc = h()
    tc.hello

 

引用:

h 也正是接收Hello类;tc
= h()实例化类;tc.hello方法,调用的其实是大家定义的fun方法。

    Hello = type('Hello',(object,),dict(hello=fun()))
    tc = Hello()
    tc.hello

 type()动态创立类后,还足以加上越多的点子和总体性:

def mysql():
    conn = pymysql.connect(host='127.0.0.1',port=3306 ,user='root' ,passwd='q123456' ,db='amsql' )
    cur = conn.cursor()
    sql = "SELECT * FROM amt_case_interface_table"
    ret = cur.execute(sql)
    print(cur.fetchmany(3))
    #conn.commit()

    cur.close()
    conn.close()

Hello.mysql = mysql()

调用:

tc.mysql

 

Linux and
python学习沟通1,2群已满.

Linux and
python学习沟通3群新开,欢迎参与,一起学习.qq 3群:563227894

不前进,不倒退,截止的动静是没有的.

一道前行,与君共勉,

 

3.1     版本一

 

新蒲京官方下载 3新蒲京官方下载 4

 1 class NameProperty:
 2     def __init__(self, name=""):
 3         self.name = name
 4 
 5     def __get__(self, instance, owner):
 6         if instance is None:
 7             return self
 8         return instance.__dict__.get(self.name)
 9 
10     def __set__(self, instance, value):
11         if not isinstance(value, str):
12             raise TypeError("name must be string")
13         instance.__dict__[self.name] = value
14         
15 
16 class Student:
17     name = NameProperty('name')
18     age = None
19     heghth = None
20     weight = None
21 
22     def __init__(self, name):
23         self.name = name
24 
25     def __str__(self):
26         return self.name
27 
28     @property
29     def age(self):
30         return self.age
31 
32     @age.setter
33     def age(self, value):
34         if not isinstance(value, int):
35             raise ValueError("must be int")
36         self.age = value
37 
38 s = Student("Stitch")
39 print(s)
40 s.name = 'name'
41 print(s.name)

View Code

 

其一本子存在多少个难点,便是name =
NameProperty(“sss”),必须安装1个称谓,才足以利用。这些与我们应用django的models时不太一致,在运用models时,不写参数也足以的。

 

3.2     版本二

不用输入变量名称。

新蒲京官方下载 5新蒲京官方下载 6

class NameProperty:
    index = 0

    def __init__(self):
        self.name = str(self.__class__.index)  # 使用类的变量
        self.__class__.index += 1

    def __get__(self, instance, owner):
        return getattr(instance, self.name)

    def __set__(self, instance, value):
        if not isinstance(value, str):
            raise TypeError("name must be string")
        instance.__dict__[self.name] = value


class Student:
    name = NameProperty()
    age = None

    def __str__(self):
        return self.name

s = Student()
s.name = "www"
print(s)

s2 = Student()
s2.name = "http"
print(s2)
print(s.name)

View Code

 

本条本子还存在3个标题,假诺一个门类有多少个字段使用了NameProperty时,错误提醒时,不能代表出此变量的名称,只好表示出3个index值。用户看到那个时,无法看清是不行变量出了难点。

 

相关文章

No Comments, Be The First!
近期评论
    功能
    网站地图xml地图