目录
仿优酷系统第一天总结
exec
exec是python解释器中的一个函数,使用方法与正常函数的使用方法是一样的
exec中有三个参数
1.包含python代码的字符串
2.全局作用域(字典形式),如果不指定,默认是globals()
3.局部作用域(字典行式),如果不指定,默认是locals()
将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) # 局部名称空间 # 1.文本形式的python代码 code = ''' x = 100 y = 200 def func(): pass ''' # 2.全名的名称空间 {} global_dict = {} # 3.局部名称空间 {} local_dict = {} exec(code, global_dict, local_dict) # print(global_dict) print(local_dict)
元类
1.什么是元类
元类就是类的类,type是所有类的类,type就是一个元类
2.元类的作用
元类可以帮助我们控制类的创建
2.如何自定义创建元类
1.自定义一个元类,继承type,派生出自己的属性与方法
2.给需要使用的类,通过metaclass指定自定义好的元类
例:
# 自定义元类 class MyMeta(type): # 子类的方法与父类的方法一样,先用子类的,子类覆盖父类的__init__方法。 # 控制了类的定义 def __init__(self, class_name, class_base, class_dict): # print(class_name) # 判断字符串首字母是否大写 if not class_name.istitle(): raise TypeError('类的首字母必须大写!') # 控制类中必须要有注释 if not class_dict.get('__doc__'): raise TypeError('类内部必须要写注释!') # print(class_base) # print(class_dict) 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 class Bar: pass # metaclass ---> 自定义的元类 # 因为Foo类继承了元类,必须手动继承object class Foo(Bar, metaclass=MyMeta): # MyMeta(Foo, Foo_name, (Bar, ), foo_dict) ''' 这是一个Foo类 ''' # 摊开坦克 x = 10 def __init__(self, y, z): self.y = y self.z = z def f1(self): print('from Foo.f1...')
仿优酷系统总结
1.仿优酷的架构
---用户视图层
---接口层
---数据层(主要)
2.数据库存储数据的格式最好是使用josn串的格式,因为json可以实现跨平台交互。保存的时候按照字典的格式来保存是因为可以利用字典的方便存取,可以通过键值对的方式进行存取。
3.数据库中的字段是有格式的,在创建字段的时候,分别是字段名 列类型 [可选参数] 约束条件,将每个字段都写成对象的格式,这样在判断字段的时候可以直接通过对象.属性的方式来进行取值,对字段进行判断。
4.在存储以及写入数据的时候都按照对象.方法的方式来进行存取,这样比较方便进行操作
5.类名.__dict可以查看类的名称空间内的所有名称,
raise TypeError('必须有一个主键') 可以返回错误
items() 会将字典中的每一项以列表的行式返回,列表中的每一项都是以键值对的行式表现
字典名.key() 遍历字典中的所有key
dict也是一个类,可以继承字典,当父类继承字典的时候,可以自由输入值,不受约束,输入的值的格式必须是键值对格式。
6.以下是今天将的ORM的一些代码
# 现在写的是数据库的表字段格式,如何去创建一个表,模仿数据库去创建一个表,表有字典,列类型,约束条件 # 先写字典字段名的列类型(字段名,数据类型,约束条件,主键,默认值) # 通过数字型和字符串类型进行抽象,找到公共部分写出来父类 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 Int(Field): def __init__(self,name,column_type='int',primary_key=False,default=0): super().__init__(name,column_type,primary_key,default) # 字符串类型 class Str(Field): def __init__(self, name, column_type='varchar(64)', primary_key=False, default=None): super().__init__(name,column_type,primary_key,default) ''' 关于字段的数据类型已经创建完成,之后在使用的时候, 直接讲需要的类型参数传进去,就可以创建出自己需要的字段类型 ''' ''' 关于表的问题:有一个数据库中有用户的表,也有存放电影的表 表的特征: 1.表名只能有一个, 2.给表强加属性,主键只能有一个,必须是唯一的 3.将数据表中所有的字段对象都存放在一个独立的字典中,目的是为了方便存取 问题1:解决代码冗余的问题,如果有一百张表,怎么办 问题2:无法预测每张表中的字段是什么,无法通过父类的__init__解决问题 问题3:继承字典的类实例化的对象,无法通过“对象.属性”的方式存取值 ''' # 写一个元类 class OrmMetaClass(type): def __new__(cls,class_name,class_base,class_dict): # class_name 类名---》表名 # class_base 基类/父类 # class_dict 类的名称空间 if class_name == 'Models': return type.__new__(cls,class_name,class_base,class_dict) # 1.一张表必须要有表名 table_name = class_dict.get('table_name',class_name) #2.主键名 primary_key = None # 3.定义一个空字典,专门用来存放字段对象 mappings = {} for key,value in class_dict.items(): # items会讲字典中的每一项以列表的行式返回,列表中的每一项都是以键值对的行式表现 # 现在拿到的键值对是名称空间中的键值对 if isinstance(value,Field): mappings[key] = value # 判断字段对象是否是主键 if value.primary_key: # 嫌犯段初始的primary_key是否为True # 判断主键是否已经存在 if primary_key: raise TypeError('只能由一个主键') # 若主键不存在,则给primari__key赋值 primary_key = value.name # 节省资源:因为mappings与元类中名称空间中的属性重复,为了节省内存,提出重复的属性 for key in mappings.key(): # 遍历字典中的key class_dict.pop(key) # pop函数用于移除列表中的元素 # 判断是否有主见 if not primary_key: raise TypeError('必须有一个主键') # 给类的名称空间添加表名 class_dict['table_name'] = table_name # 给类的名称空间添加主键名 class_dict['primary_key'] = primary_key # 给类的名称空间添加一个mappings字典,字典中拥有所有字段属性 class_dict['mappings'] = mappings return type.__new__(cls,class_name,class_base,class_dict) # 根据用户表与电影表信息创建一个父类 class Models(dict): def __getattr__(self, item): print(item,'对象.属性没有的时候触发') return self.get(item) # 给对象添加属性的时候触发,对象.属性=值 def __setattr__(self, key, value): self[key] = value # 先建立用户表 class User(Models,metaclass=OrmMetaClass): user_id = Int(name='user_id',primary_key=True) user_name = Str(name='name') pwd = Str(name='pwd') ''' 当父类继承字典的时候,这种写法,可以自由输入值,不受约束,输入的值的格式必须是键值对的格式 ''' # 视频表 class Movies: def __init__(self,movies_id,movies_name,movies_string): pass