11.4 summary

A, exec module

1. What is? Python is a built-exec module.

2.exec role:

'''
x=10
def func():
   pass
'''

Can be "string" Python code, added to the global or local namespace.

3. how to use:

Parameter 1: Python code string

Parameter 2: global name space dictionary

Parameter 3: Local namespace dictionary

Call exec ()

#添加到全局名称空间
#1.文本形式的Python代码
code='''
global x
x=10
y=20
'''
#2.全名的名称空间{}
global_dict={'x':200}
#3.局部名称空间{}
local_dict={}

exec(code,global_dict,local_dict)
print(global_dict)
运行结果:
x=10,....
#添加到局部名称空间
#1.文本形式的Python代码
code='''
x=100
y=200
def func():
   pass
'''
#2.全局的名称空间
global_dict={}
#3.局部的名称空间{}
local_dict={}

exec(code,global_dict,local_dict)
print(local_dict)
运行结果:
{'x': 100, 'y': 200, 'func': <function func at 0x0000000001FF2E18>}

Second, Moto类

1. What is a metaclass:

Yuan class is the class of the class, the class is a type of Chinese class, the class type is all class, type is a metaclass.

2. Yuan class action:

Yuan class can help create our control class

Yuan class can call our help control class

创建类有两种方式:
1.通过class 关键字创建类,内部会自动调用type(),type帮我们创建一个自定义类。
2.通过手动调用type()实例化得到自定义的类。
#1.class创建
'''python中,一切皆对象'''
class Chinese:
    country='China'
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def speak(self):
        print('speak chinese..')

p1=Chinese('tank',18)
print(Chinese)
print(p1)
print(type(p1))
print(type(Chinese))  #type类

#type()-->Chinese--对象
#Chinese()--p1
运行结果:
<class '__main__.Chinese'>
<__main__.Chinese object at 0x000000000284C710>
<class '__main__.Chinese'>
<class 'type'>
#2.type创建:
class_name='Chinese'
class_base=(object, )
class_dict={}
code='''
country="china"
def __init__(self,name,age):
   self.name=name
   self.age=age
def speak(self):
   print("speak chinese..")
'''
exec(code,{},class_dict)
Chinese=type(class_name,class_base,class_dict)
print(Chinese)
运行结果:
<class '__main__.Chinese'>

3. how to create a custom metaclass:

1) a custom metaclass, inheritance type, derive their properties and methods.

2) to the class required by the self-defined metaclass specified metaclass.

#自定义元类
class MyMeta(type):
    #子类的方法与父类的方法一样,先用子类的,子类覆盖父类的__init__方法。
    #控制子类的定义:
    def __init__(self,class_name,class_base,class_dict):


        #判断字符串首字母是否大写
        if not class_name.istitle():
            raise TypeError('类的首字母必须大写!')

        #控制类中必须要要注释
        if not class_dict.get('__doc__'):
            raise TypeError('类内部必须要写注释!')

        super().__init__(class_name,class_base,class_dict)

    #模拟type元类内部做的事情
    #元类触发的__call__可以控制类的调用,调用__call__会触发以下两点
    def __call__(self,*args,**kwargs):
        #1.会调用__new__()--obj,会创建一个空对象
        obj=object.__new__(self)
        #2.会执行__init__(obj,*args,**kwargs)
        obj.__init__(*args,**kwargs)
        return obj

    #可以通过元类内部的__new__控制对象的创建
    # def __new__(cls, *args, **kwargs):
    #     pass

# metaclass-->自定义的元类
# 因为Foo类里边什么都不写是默认继承了父类object,因为它继承了元类,所以手动添加它的父类object,什么都不写是默认继承了父类object
class Foo(object,metaclass=MyMeta):
    '''
    这是一个类
    '''
    x=10
    def __init__(self,y,z):
        self.y=y
        self.z=z

    def f1(self):
        print('from Foo.f1..')

foo=Foo(20,30)   #调用Foo对象,会触发__call__

Three, ORM: Object-relational mapping

ORM: mapped to the database in MySQL data tables

Class name -> table name

Object -> a record

Object Properties -> Fields

Simulation of the ORM Django, the database will add, delete, change, all packaged as a one way, for example: save, delete, update, select.

#1.创建字段的类型,对应数据表中的一个个字段的创建规范
class Field:
    def __init__(self,name,column_type,primary_key,default):
        self.name=name
        self.column_type=column_type
        self.primary_key=primary_key
        self.default=default

class IntegerField(Field):
    def __init__(self,name,column_type='int',primary_key=False,default=0):
        super().__init__(name,column_type,primary_key,default)

class StringField(Field):
    def __init__(self,name,column_type='varchar(64)',primary_key=False,default=None):
        super().__init__(name,column_type,primary_key,default)
# class Father:
#     def __init__(self,*args,**kwargs):
#         self.id=id
#         self.username=args[0]
#         self.password=args[1]
#         self.photo=args[2]

class Models(dict):

    #会在对象.属性没有时触发
    def __getattr__(self, item):
        print(item,'调用没有的属性时会触发..')
        #将字典中key对应的值,返回给对象
        return self.get(item)  #dict_obj.get(key)

    #在对象.属性=值时触发
    def __setattr__(self, key, value):
        print(key,value)
        #给字典对象本身赋值
        self[key]=value

#创建数据表类
#用户表类
class User(Models):
    #强调:最好与字段类型的name属性同名
    user_id=IntegerField(name='user_id')
    user_name=StringField(name='name')
    pwd=StringField(name='pwd')

#电影表类
class Movie(Models):
    pass

user=User(id='007',name='tank',pwd='123')
print(user)
print(type(user))
movie=Movie(m_id='1',m_name='写真集')
print(movie)
print(type(movie))

#字典的取、存值方式
print(user['id'])
user['age']=18
print(user.get('id'))
print(user.get('age'))

user.age=18
print(user.age)

user.sex='male'
print(user.sex)
print(user['sex'])
print(user.__dict__)
运行结果:
{'id': '007', 'name': 'tank', 'pwd': '123'}
<class '__main__.User'>
{'m_id': '1', 'm_name': '写真集'}
<class '__main__.Movie'>
007
007
18
age 18
age 调用没有的属性时会触发..
18
sex male
sex 调用没有的属性时会触发..
male
male
{}
'''
问题1:解决代码冗余问题,比如有100张表,需要写100次__init__
解决1:继承一个父类,父类中定义一个__init__

问题2:无法预测每一张表中的字段是什么,无法通过父类的__init__ 解决问题
解决2:通过继承字典,内部的__init__,可以接受‘任意个数’的‘关键字参数’

问题3:继承字典的类实例化的对象,无法通过‘对象.属性的方式存取值
解决3:通过__setatter__,__getattr__来实现,让字典对象与普通对象一模一样,并且具备字典原有的特性
'''

Guess you like

Origin www.cnblogs.com/lidandanaa/p/11795595.html