复习
类
对象
实例化过程:
组合:
super 派生prop
多态:建立一个父类,让所有传递的数据类型都继承这个父类。
学习方法: xy rz 时间
1.画知识的思维导图:思维导图一定要画!
python:基础数据类型 文件处理 函数 模块 面向对象
整理;时间分片
1 # 面向对象 2 # 类 实例化 对象/实例 3 # 什么是类? 拥有相同属性和方法的一类事物 4 # 什么是对象? 类的一个实际表现,给类中的属性填上具体的值,能够使用类中的方法 5 # 实例化的过程中做了那些事儿? 6 # 对象 = 类名() 7 # 首先要创造一个对象 8 # 被创造出来的这个对象会作为参数传递给__init__方法中的第一个参数 9 # 调用__init__方法,传递一些初始化参数 —— 初始化方法 10 # 将初始化之后的对象返回给调用者 11 # 查看属性和调用方法 12 # 类名 : 静态属性、类属性 13 # 对象 : 调用方法(动态属性)、查看对象的属性 14 # 组合 : 两类事物之间的所有关系,什么有什么的关系 15 # 继承 :两个类之间的包含关系,什么是什么的关系 16 # 钻石继承问题 17 # 经典类 : 在一个子类中寻找方法的时候,从子类到父类先找到的名字会被执行。 18 # 深度优先就是在经典类中找类的顺序的一种算法 19 # 新式类 : 广度优先 20 # py2中,主动继承object类的都是新式类,它的子类也是新式类 21 # py3中,所有的类都是新式类,都继承object 22 # super : 23 # 自己有父类也有的时候,在单继承中super就可以用父类的 24 # 在多继承中 super遵循mro广度优先顺序 25 # 派生 : 26 # 属性 27 # 方法 28 # 多态 29 # python中不需要程序员自己实现多态 30 # 在其他强数据类型语言的面向对象中,我要传递一个参数必须指定这个参数的数据类型 31 # 但是,往往在这个地方需要传递的不止一种类型 32 # 建立一个父类,让所有要传递的数据类型都继承这个父类,在参数指定数据类型的时候 33 # 指定父类名就可以了 34 35 # def eat(Animal alex):pass 36 37 38 # 画知识的思维导图:思维导图一定要画! 39 # python :基础数据类型 文件处理 函数 模块 面向对象 40 # 函数 41 # 函数的定义 :参数和返回值 42 # 生成器函数 43 # 递归函数 44 # 内置函数 45 # 匿名函数 46 # 面向对象 47 # 基础概念 48 # 定义 49 # 三大特性 : 封装 50 # 多态 51 # 继承 52 53 # 北大研究生 : 54 # 整理 55 # 时间分片
一、封装
广义的封装:把变量和函数都放在类中
狭义的封装:把一些变量或方法隐藏起来,不对外公开
公有的;
私有的:__name
例子一
1 #例子一 2 # class Person: 3 # __country='中国' #私有的静态属性 4 # print(__country) #类里的代码,从定义开始就执行,会输出 中国 5 # 6 # #print(Person.__country) #AttributeError: type object 'Person' has no attribute '__country' 7 # #私有的名字 ,只能在类的内部使用,不能在类的外部使用 8 # 9 # print(Person._Person__country)#可以调用,但不能使用该方式。 10 # print(Person.__name) #在类的外部不能定义一个私有变量
私有的变量:在类的内部 如果使用__变量的形式会发生变形,python会自动的为你加上_类名
例子:用户名密码--变形
1 class Person: 2 __country = '中国' 3 def __init__(self,name,pwd): 4 self.name = name 5 self.__pwd = pwd # 私有的对象属性 6 def login(self): 7 print(self.__dict__) 8 if self.name == 'alex' and self.__pwd == 'alex3714': 9 print('登录成功') 10 11 alex = Person('alex','alex3714') 12 alex.login() 13 print(alex.__dict__) #{'name': 'alex', '_Person__pwd': 'alex3714'} 14 print(alex.__pwd)
不允许调用类中的私有属性!! 例子--制造密码
# class Person: # def __init__(self):pass # def __制造密码转换(self,inp): # print('eating') # def 注册(self): # inp = input('pwd>>>') # 加密之后的密码 = self.__制造密码转换(inp)
# 静态属性 、 对象属性、 方法(动态属性) 前面加上双下划綫都会变成私有的
# 私有的特点就是只能在类的内部调用,不能在类的外部使用!!
面试题 in Foo
1 # class Foo: 2 # def __init__(self): 3 # self.__func() # self._Foo__func 4 # def __func(self): 5 # print('in Foo') 6 # 7 # class Son(Foo): 8 # def __func(self): # _Son__func 9 # print('in son') 10 # 11 # s = Son()
1 # class Foo: 2 # def __init__(self): 3 # self.func() 4 # def func(self): 5 # print('in Foo') 6 7 # class Son(Foo): 8 # def func(self): 9 # print('in son') 10 # 11 # s = Son()
二、类中的装饰器方法:
三个装饰器函数:classmethod staticmethod property(将一个函数伪装成属性 @property 重要)
圆形类 面积 打折--修改删除不常用 property 必须掌握
1 from math import pi 2 class Circle: 3 def __init__(self,r): 4 self.r=r 5 @property 6 def area(self): 7 print('area被执行了...') 8 return self.r**2*pi 9 @property 10 def perimeter(self): 11 return self.r*2*pi 12 # # 方法 动词 —— 动作或者技能 13 # # 名词 圆的面积 圆的周长 圆的班级 14 #将一个函数伪装成属性 @property 15 16 c=Circle(3) 17 print(c.area) 18 print(c.perimeter)
1 # #练习计算面积--zijixiede 2 # class mj: 3 # def __init__(self,l,h): 4 # self.l=l 5 # self.h=h 6 # @property 7 # def area(self): 8 # return self.h *self.l 9 # ss=mj(2,3) 10 # print(ss.area)
1 #property 和 __私有的名字一起使用----------打折例子 2 3 class Goods: 4 def __init__(self,price,discount): 5 self.__price=price 6 self.discount=discount 7 @property 8 def price(self): 9 return self.__price * self.discount 10 @price.setter #修改价格 11 def price(self,newprice): 12 self.__price=newprice 13 @price.deleter #删除 14 def price(self): 15 del self.__price 16 17 apple=Goods(8,0.7) 18 print(apple.price) 19 apple.price=10 20 print(apple.price) 21 print(apple.__dict__) 22 del apple.price 23 print(apple.__dict__) 24 # print(apple.price) 25 26 结果: 27 5.6 28 7.0 29 {'_Goods__price': 10, 'discount': 0.7} 30 {'discount': 0.7}
国籍例子--classmethod 变成类方法。使用场景:# 如果某一个类中的方法 并没有用到这个类的实例中的具体属性
# 只是用到了类中的静态变量 就使用类方法
1 # class Person: 2 # Country = '中国人' 3 # @classmethod #把func变成了一个类方法 4 # def func(cls): # cls是指向类的内存空间 5 # print('当前的角色的国籍是%s'%cls.Country) 6 7 # alex = Person() 8 # alex.func() 9 # Person.func() 10 # 如果某一个类中的方法 并没有用到这个类的实例中的具体属性 11 # 只是用到了类中的静态变量 就使用类方法
登录例子--如果一个方法,既不会用到对象中的属性也不会用到类中的属性,就应该被定义为一个静态方法 staticmethod
1 class Student: 2 @staticmethod 3 def login(): 4 name = input('name : ') 5 pwd = input('pwd : ') 6 if name =='' and pwd =='': 7 print('实例化') 8 9 Student.login()
三、序列化模块 非常重要
1.什么叫序列化:数据类型-->字符串的过程
2.用序列化情况:固态存储;网络传输
3.模块:
json 通用的 支持的数据类型 list tuple dict
pickle python中通用的 ,支持几乎所有python中的数据类型
shelve python中使用的便捷的序列化工具
4个方法 及例子
dumps 内存中做操作 字典转字符串的过程 ——序列化
loads 内存中做操作 字符串 转回其他数据类型 —— 反序列化
dump 和文件交互 一次性写的数据,只能一次性读出
load 从文件中反序列化 不能多次load解决办法:
如果要dump多条数据,每一条数据先dumps一下 编程字符串 然后打开文件 write写进文件里
读取的时候按照标志读取或者按行读
读出来之后,再使用loads
1 # 什么叫序列化呢? 2 # { '10100011':{'name':,age: ,class:},} 3 # 数据类型 —— 字符串的过程 4 # 什么时候要用序列化呢? 5 # 数据从内存到文件 6 # 数据在网络上传输 字节 - 字符串 - 字典 7 # python中的序列化模块都有哪些? 8 # json 通用的 支持的数据类型 list tuple dict 9 # pickle python中通用的 支持几乎所有python中的数据类型 10 # shelve python中使用的便捷的序列化工具 11 12 # dumps loads 13 # dump load 14 15 import json 16 dic = {"k":'v'} 17 # print(type(dic)) 18 # json_dic = json.dumps(dic) #{"k": "v"} # 字典转字符串的过程 ——序列化 19 # print(json_dic) 20 # print(dic) #{'k': 'v'} 21 # print(type(json_dic)) 22 # print(json.loads(json_dic)) # 字符串 转回其他数据类型 —— 反序列化 23 24 # with open('d','w') as f: 25 # json.dump(dic,f) # dump是和文件交互的 26 # json.dump(dic,f) # dump是和文件交互的 27 28 # with open('d') as f: 29 # print(json.load(f)) # 从文件中反序列化 30 31 # 如果要dump多条数据 32 # 每一条数据先dumps一下 编程字符串 然后打开文件 write写进文件里 33 # 读取的时候按照标志读取或者按行读 34 # 读出来之后 再使用loads
例子
# with open('aaa','w') as f: # str_dic = json.dumps(dic) # f.write(str_dic+' ') # f.write(str_dic+' ') # f.write(str_dic+' ') # f.write(str_dic+' ') # with open('aaa') as f: # for line in f: # print(json.loads(line.strip()))
pickle 对象序列化文件 例子 打印出显示二进制类型的,要以wb打开,要以rb去读
dump,load取值就行,加异常处理
1 # import pickle 2 # class A: 3 # def __init__(self,name): 4 # self.name = name 5 # 6 # alex = A('alex') 7 # print(pickle.dumps(alex)) 8 # with open('bbb','wb') as f: 9 # pickle.dump(alex,f) 10 # pickle.dump(alex,f) 11 # pickle.dump(alex,f) 12 # 13 # with open('bbb','rb') as f: 14 # while True: 15 # try: 16 # obj = pickle.load(f) 17 # print(obj.name) 18 # except EOFError: 19 # break
pickle与json区别
1.pickle支持更多的数据类型
2.pickle的结果是二进制
3.pickle在和文件交互的时候可以被多次load
shelve读博客--不常用 不能同时进行写操作
网络传输
四、三个模块
1.hashlib模块 重要 摘要算法 单向不可逆
2.logging模块 重要
3.configparse模块 一般
1.hashlib模块:以后登录都要加密密码!!!
作用1:存储用户密码的时候,不要存储明文
包含了多种算法的模块
将一个字符串进行摘要运算,拿到一个不变的 固定长度的值
md5算法:32位
sha算法:数字越大,越复杂,时间越长,结果越长 sha1 40位
import hashlib #hashlib.md5()#<md5 HASH object @ 0x000000000218C8A0>一种算法 md5obj=hashlib.md5() #实例化一个md5摘要算法的对象 # 能够让一个字符串 唯一的 对应一个固定的值 md5obj.update('lijie123'.encode('utf-8')) #使用md5算法的对象来操作字符串 #获取算法的结果 ret=md5obj.hexdigest() print(ret,type(ret),len(ret))
撞库 别人有一个庞大的库,存储了很多字符串和MD5值得关系
有了加盐 例子
动态加盐 userinfo表 把username作为盐 例子
作用2:校验文件一致性
分多次对一个文件进行摘要结果一致
练习题:。。。
1 # 登录 —— hashilib 2 # 数据库泄露 3 # 存储用户密码的时候 : 不要存储明文 4 # 对用户输入的密码进行一种计算 计算之后 会得到一个新的 固定的 字符串 5 6 # hashlib模块 摘要算法 ---> 单向不可逆 7 # 包含了多种算法 8 # 将一个字符串进行摘要运算 拿到不变的 固定长度的值 9 # import hashlib 10 # md5obj = hashlib.md5() # 实例化一个md5摘要算法的对象 11 # md5obj.update('alex3714'.encode('utf-8')) # 使用md5算法的对象来操作字符串 12 # ret = md5obj.hexdigest() # 获取算法的结果 hex+digest 16进制+消化 13 # print(ret,type(ret),len(ret)) 14 # 注册 :alex3714 -摘要-> 文件里 15 # 登录 :alex3714 -摘要-> 和文件里比对 16 # md5obj = hashlib.sha1() # 实例化一个md5摘要算法的对象 17 # md5obj.update('alex3714'.encode('utf-8')) # 使用md5算法的对象来操作字符串 18 # ret = md5obj.hexdigest() # 获取算法的结果 hex+digest 16进制+消化 19 # print(ret,type(ret),len(ret)) 20 21 # 撞库 22 # 别人有一个庞大的库 :字符串 --> md5值的关系 23 # 加盐 24 # md5obj = hashlib.md5('tesla'.encode('utf-8')) # 实例化一个md5摘要算法的对象,加盐 25 # md5obj.update('alex3714'.encode('utf-8')) # 使用md5算法的对象来操作字符串 26 # ret = md5obj.hexdigest() # 获取算法的结果 hex+digest 16进制+消化 27 # #aee949757a2e698417463d47acac93df 28 # print(ret) 29 30 # 动态加盐 31 # userinfo表 32 # username = 'alex' 33 # md5obj = hashlib.md5(username.encode('utf-8')) # 实例化一个md5摘要算法的对象,加盐 34 # md5obj.update('alex3714'.encode('utf-8')) # 使用md5算法的对象来操作字符串 35 # ret = md5obj.hexdigest() # 获取算法的结果 hex+digest 16进制+消化 36 # #aee949757a2e698417463d47acac93df 37 # print(ret) 38 39 # 校验文件一致性 40 # 自动化 —— python代码来做验证 41 # import hashlib 42 # md5obj = hashlib.md5() # 实例化一个md5摘要算法的对象 43 # md5obj.update('alex'.encode('utf-8')) # 使用md5算法的对象来操作字符串 44 # md5obj.update('3714'.encode('utf-8')) # 使用md5算法的对象来操作字符串 45 # print(md5obj.hexdigest()) 46 47 # aee949757a2e698417463d47acac93df 48 # aee949757a2e698417463d47acac93df 49 50 # 写一个函数 接收两个文件的地址 返回T/F
2.configparse模块 一般
快速处理配置文件 创建 实例化-字典
查看 default 类似于全局变量
用到的时候去博客中查看即可
1 import configparser 2 3 # config = configparser.ConfigParser() 4 # config["DEFAULT"] = {'ServerAliveInterval': '45', 5 # 'Compression': 'yes', 6 # 'CompressionLevel': '9', 7 # 'ForwardX11':'yes' 8 # } 9 # 10 # config['bitbucket.org'] = {'User':'hg'} 11 # config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'} 12 # with open('example.ini', 'w') as f: 13 # config.write(f) 14 15 import configparser 16 17 config = configparser.ConfigParser() 18 print(config.sections()) 19 config.read('example.ini') 20 print(config.sections()) # ['bitbucket.org', 'topsecret.server.com'] # DEFAULT --> 全局 21 22 # print('bytebong.com' in config) # False 23 # print('bitbucket.org' in config) # True 24 # print(config['bitbucket.org']["user"]) # hg 25 # print(config['DEFAULT']['Compression']) #yes 26 # print(config['topsecret.server.com']['ForwardX11']) #no 27 # print(config['bitbucket.org']) #<Section: bitbucket.org> 生成器 28 # for key in config['bitbucket.org']: # 注意,有default会默认default的键 29 # print(key) 30 # print(config.options('bitbucket.org')) # 同for循环,找到'bitbucket.org'下所有键 31 # print(config.items('bitbucket.org')) #找到'bitbucket.org'下所有键值对 32 # print(config.get('bitbucket.org','compression')) # yes get方法Section下的key对应的value 33 34 import configparser 35 # config = configparser.ConfigParser() 36 # config.read('example.ini') 37 # config.add_section('yuan') 38 # config.remove_section('bitbucket.org') 39 # config.remove_option('topsecret.server.com',"forwardx11") 40 # config.set('topsecret.server.com','k1','11111') 41 # config.set('yuan','k2','22222') 42 # 43 # config.write(open('example.ini', "w"))
3.logging模块--日志模块 重要
程序执行的中间过程--需要记录下来
程序出错---日志 对内看的
给用户看的---对外看的
用法:1.简单配置 例子
参数:level,加format参数 ,detefmt,filename,filemode
--中文存在乱码,屏幕与文件不能同时展示
1 # import logging 2 # logging.basicConfig(level=logging.DEBUG) #显示DEBUG及以上的信息 3 # logging.debug('debug message') #非常细节的日志--排查错误的时候使用 4 # logging.info('info message') #正常的日志信息 5 # logging.warning('warning message') 6 # logging.error('error message') #错误 7 # logging.critical('critical message') #严重错误 8 # 9 # 10 # 11 # logger=logging.getLogger() 12 # fh=logging.FileHandler('log.log') #创造了一个能操作文件的对象fh 13 # logger.addHandler(fh) 14 # 15 # sh=logging.StreamHandler() #在screen输出 16 # logger.addHandler(sh) 17 # logger.warning('warning message') 18 # 19 # #创造一个格式 20 # format='...' 21 # sh.setFormatter(format) 22 # #logger里设置级别 设置encoding,在文件名之后
2.logger对象的方式配置
logger=logging.getLogger()
往文件中输入 写法,参数
1 # logging 2 # 日志 3 # 程序出错 -- 日志 对内看的 4 # 给用户看的 对外看的 5 import logging 6 # 简单配置 7 # logging.basicConfig(level=logging.DEBUG, 8 # format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', 9 # datefmt='%a, %d %b %Y %H:%M:%S', 10 # filename='test.log', 11 # filemode='w' 12 # ) 13 # logging.debug('debug message') # 非常细节的日志 —— 排查错误的时候使用 14 # logging.info('info message') # 正常的日志信息 15 # logging.warning('warning message') # 警告 16 # logging.error('error message') # 错误 17 # logging.critical('critical message') # 严重错误 18 19 # logger对象的方式配置 20 logger = logging.getLogger() 21 # 吸星大法 22 23 # 先创造一个格式 24 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 25 formatter1 = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') 26 27 # 往文件中输入 28 fh = logging.FileHandler('log.log',encoding='utf-8') # 创造了一个能操作文件的对象fh 29 fh.setFormatter(formatter) # 高可定制化 30 logger.addHandler(fh) 31 logger.setLevel(logging.DEBUG) 32 sh = logging.StreamHandler() 33 sh.setFormatter(formatter1) 34 logger.addHandler(sh) 35 36 fh.setLevel(logging.ERROR) 37 sh.setLevel(logging.DEBUG) 38 39 40 logger.debug('logger debug message') 41 logger.info('logger info message') 42 logger.warning('logger warning message') 43 logger.error('程序出错了') 44 logger.critical('logger critical message')
五、反射!! 及面向对象进阶
!!!!!!反射 百分重要
定义:通过字符串数据类型的 变量名,来访问变量的值
1 # 什么叫反射 2 # 通过字符串数据类型的 变量名 来访问变量的值 3 4 # name = 'value' 5 6 # eval('') 7 8 # 类名 反射 静态属性 9 # 对象名 反射 对象属性 和 方法 10 # 模块 反射 模块中的名字 11 # 反射 自己所在文件中的名字 12 13 # x.y 这样的形式 都可以用反射 14 15 # print('aaa'.startswith) 16 # print('aaa'.startswith('a')) 17 # # 'startswith' 18 # ret = getattr('aaa','startswith') 19 # print(ret('a'))
使用场景:
1.类名 反射 静态属性
2.对象名 反射 对象属性和方法
1 class Person: 2 role='Person' 3 def __init__(self,name): 4 self.name=name 5 def eat(self):print('eating') 6 def drink(self):print('drinking') 7 def play(self): print('playing') 8 def sleep(self): print('sleeping') 9 10 #1.类名 反射 静态属性 11 print(getattr(Person,'role')) #Person 12 #2.对象名反射属性 13 alex=Person('alex') 14 print(getattr(alex,'name')) #alex 15 16 #2.对象名反射方法 17 # while True: 18 # inp = input('>>>') #注意input在上面 19 # if hasattr(alex,inp): 20 # getattr(alex,inp)() #不加括号拿到内存地址 21 #小结: 22 # 首先 使用getattr取获取一个名字,如果在这个对象的命名空间中没有这个名字 会报错 23 # getattr的反射好伴侣 hasattr 24 # 如果使用getattr取获取一个方法,那么只能拿到这个方法的内存地址 加上括号就是执行,当然,括号里的参数可以照传不误 25 # 如果getattr获取一个属性,那么直接使用反射就可以获取到值
3.模块 反射 模块中的名字 (属性方法 类中的)
4.反射自己所在文件中的名字!!
sys.modules['__main__'] 例子
1 #3.模块 反射 模块中的名字 (属性方法 类中的) 2 # import mymodule 3 import time 4 5 # mymodule.func1() 6 # time.sleep(0.5) 7 # print(mymodule.money) 8 # getattr(mymodule,'func1')() #调用方法 9 # print(getattr(mymodule,'money')) #调用属性 10 # getattr(time,'sleep')(1) #调用sleep 11 #调用类中的 12 # Manager = getattr(mymodule,'Manager') #拿到manager 13 # a = Manager() #实例化 14 # a.eat() 15 16 # 4.反射 自己所在文件中的名字 17 value = '123' 18 def func1(): 19 print('func1') 20 class Manager: 21 def eat(self): 22 print('eating') 23 import sys 24 print(sys.modules['__main__']) #取到模块 25 print(getattr(sys.modules['__main__'],'value')) #取value值 26 # print(getattr(sys.modules['__main__'],'func1'))() #反射方法 27 #反射类 28 Manager=getattr(sys.modules['__main__'],'Manager') 29 Manager().eat() #eating
1 # 模块就是一个py文件 2 # 所谓的模块导入 就是执行了这个文件而已 3 money = 100 4 def func1(): 5 print('func1') 6 7 def func2(): 8 print('func2') 9 10 class Manager: 11 def eat(self): 12 print('eating')
x.y的形式,都可以用反射
作业例子--不同管理员执行不同的权限
1 class Manager: 2 def __init__(self,name): 3 self.name = name 4 def create_course(self): 5 pass 6 class Teacher: 7 def __init__(self,name): 8 self.name = name 9 def list_student(self): 10 pass 11 class Student: 12 def __init__(self,name): 13 self.name = name 14 15 a = Student('a') 16 a.age = 19 17 setattr(a,'age',25) 18 print(a.__dict__) 19 print(a.age) 20 import sys 21 #1.先登录 账户密码 22 #login name,pwd 23 24 id = 'Manager' 25 if hasattr(sys.modules['__main__'],id): 26 obj = getattr(sys.modules['__main__'],id)()
isinstance和issubclass两个方法不常用
setattr设置属性--了解
delattr 删除属性--了解 obj对象
__new__方法 !非常重要 面试经常被问! Foo例子
__new__方法 构造方法,创建一个对象
__init__初始化方法
先执行new方法,object.new() 再执行init
经历过程:
# Foo() --> python解释器接收到你的python代码
# python解释器替你去做了很多操作
# 包括 主动帮助你 调用 new方法 去创造一个对象 —— 开辟内存空间 —— python语言封装了开辟内存的工作
# object的new方法里 —— 帮你创造了对象
# 调用init用到的self参数 就是new帮你创造的对象
什么叫单例模式:
设计模式--23种(赵博士以后会讲)
单例模式:某一类只有一个实例 person例子 解释孩子例子
__len__ 例子,类中的内置方法,很多都和内置函数相关!
__str__ 重要!str方法必须返回字符串类型
其它自己看看!
六、项目规范
模块就是一个py文件
所谓的模块导入 就是执行了这个文件而已
# sys.path 列表里存储了所有模块导入的路径
软件开发规范 项目名称不要用中文,不要太长
bin conf..core db log(登录信息和操作信息)..图
sys.path 在pycharm中路径不准,可在cmd中查看
所有的模块导入,都需要精确到具体的模块
from core import core2
core2.login()
当一个文件 被直接执行的时候,这个文件的__name__属性是__main__
当这个文件被当做模块导入的时候,这个文件的__name__属性是文件名
core2 maneger文件(在此文件中from)
注:不能循环引用
config目录:userinfo_path='copy path即可'
从start.py执行,,,,导入core中
settings两种写法。。。绝对路径或join那种