2.python基础之内置模块认识

一、time模块


       (1)概念:系统函数与一些模块就是python写好的
       (2)调用模块  import time
            查看time有哪些功能,用help函数查 print(help(time)):提供了操作时间值的内容,时间有三种表达方式
            1.模块的内置方法
                print(time.time())---打印当前时间戳
                print(time.clock())---6.9e-07()6.9*10的负7次方,表CPU执行的时间
                print(time.sleep(3))---本身cup执行很短,但与内存等了3s
                print(time.gmtime())---时区,东边国家先见太阳,地球划24个时区,一个时区1个小时,北京是东8区,英国是UTC时间中心时间,中国是CST时间
                                     这个打印的是当前UTC时间,年月日
                print(time.localtime())---当前中国时区的时间,本地时间,年月日(tm_year=2016,tm_mon=9...)
                print(time.strftime(format,p_tuple))---struct=time.localtime print(time.strftime('%Y-%m-%d %H:%M:%S',struct))
                print(time.strptime(string,format))--2020-11-13 00:00:00  %Y-%m-%d %H:%M:%S----结果是tm_year=2016,tm_mon=9...就变为元组了,这时就可以赋给变量取里面的值了
                print(time.ctime())--当前时间,固定时间格式,Mar 20 20:20:20 2016
                               print(time.ctime(16389348))--把时间戳转为这个格式
               print(time.mktime(format))--print(time.mktime(time.localtime()))---转化为时间戳

       (3)import datetime
            print(datatime.datetime.now())---2016-10-10 00:00:00 16893929

 

二、random模块(随机数)


 

       (1)内置方法
            print(random.random())--0-1之间的随机数
            print(random.randint(1,8))--是一个范围值,整型,包括8
            print(random.choice('hello'))---参数里的随机数,参数是序列
            print(random.sample(序列))---随机在序列里取出多个
            print(random.randrange(1,3))--里面参数也是一个范围值,随机在一范围内取一个不包括3
       (2)生成验证码
             生成5位数字验证码
              def v_code():
                  code=''
                  for i in range(5):
                      add_num=random.randrange(10)----在0-10里取
                      code+=str(add_num)
                  print(code)
             生成数字带字母的验证码,数字如何变为字母?---有一个内置函数chr能把65-91的数字变为任意字母
              def v_code():
                  code=''
                  for i in range(5):
                      add=random.choice([random.randrange(10),chr(random.randrange(65,91)])

                  print(code)    

 

三、os模块(与系统交互)


 

       (1)调用系统命令,常用的调用命令(windows与Linux都可以用,但参数路径不一样有的是\有的是/import os 
           print(os.getcwd())----打印当前系统windows的工作目录
           print(os.chdir(r'C:\User'))---切换工作目录
           print(os.curdir):相当于.返回当前目录
           print(os.pardir):相当于..返回上级目录
           print(os.makedirs('abc\\alex')):创建多级目录,多一个\表转义
           print(os.removedirs('abc\\alex')):删除多级文件夹,如果这个文件夹里有文件就删不了了,它只能删空文件夹
           print(os.mkdir('dirname')):只能生成一个文件夹,生成路径最后一个是文件夹
           print(os.rmdir('dirname')):删除一个空文件夹
           print(os.listdir(r'C:\User'))-----展示目录下的所有文件,其中r表示原生字符串,后面的参数没有特殊意思全是普通字符
           print(os.remove('adc.txt')):删除文件
           print(os.rename('oldname','newname')):给文件或目录重命名,可不带扩展名
           print(os.stat('path/filename')):获取目录/文件信息,st_size=12:表文件大小,里面内容有多少  st_atime=124434341:文件最后访问时间  st_mtime=299239:修改时间
                 os.stat('path/filename').st_size
           print(os.sep):当前系统的路径分隔符不带()是变量名带()调用了是一个值,windows是\  linux是/,用它可以直接用这个值做分隔符 若k=os.sep
                          C:kUserskAdmin
           print(os.linesep):windows用\r\n做转行符,linux用\n做转行符
           print(os.pathsep):输出用于分割文件路径的字符串,eg:环境变量,windows用;做路径之间的分隔符,linux用:做环境变量分隔符
           print(os.name):输出字符串指示当前使用平台,win--nt   linux--posix
           print(os.system('bash command')):执行系统命名,windows与Linux的都行
           print(os.environ):打印出现有的环境变量
           *print(os.path.abspath('./abc')):打印某文件或目录的绝对路径
           print(os.path.split(/path)):分隔出路径与文件名,做为一个元组
           *print(os.path.dirname('C:\User\abc.txt')):打印某文件的绝对目录路径,不带文件
           print(os.path.basename(path)):返回path最后的文件句
           print(os.path.exists(path)):判断该路径是否存在,存在是true,不存在是false
           print(os.path.isabs(path)):如果path是绝对路径就返回true
           print(os.path.isfile(path)):如果path是一个存在的文件,返回true否则false
           print(os.path.isdir(path)):如果path是一个存在的目录,则返回true
           *print(os.path.join([path1 ,path2, ..] )):路径组合,将多个路径组合后返回,
           print(os.path.getatime(path)):返回path所指向文件或目录的最后存取时间
           print(os.path.getmtime(path)):返回path所指向的文件或目录的最后修改时间

 

四、hashlib模块


  加密,明文传密文(MD5加密,加密是唯一的,明文加密成密文都是一样的)

       (1)加密方法(以下都是不可逆的)
            1.md5加密
            import hashlib
            m=hashlib.md5()--md5的对象
            m.update('hello world'.encode('utf8'))---python3要做一个字符转换,
在Python3写的hello world是Unicon类型,要把它解码为字节类型(二进制,byte类型),
因为update参数必须是二进制数 m.digest()
---转换成十进制,用print打印出来 m.hexdigest()--转换成十六进制 新加一个参数会在hello world的原值上基础上再加密 m.update('alex'.encode(utf8)) m.hexdigest() m.update('hello worldalex'.encode(utf8))---这个值就跟上一个值是一样的,说明是把字符更新后再一起加密的 2.sha加密(1 224 256 368,一般256用的多些) s=hashlib.sha256() s.update('hello world'.encode('utf8')) print(s.hexdigest())

 

五、logging模块,日志模块


 

        1.原来写日志是打开一个文件用write写进去
        2.import logging 
          日志级别:critical>error>warning>info>debug,以下内容直接打印只有后三个有显示,前二个级别不够,里面的参数是自己写的内容
            logging.debug('debug message')
            logging.info('info message')
            logging.warning('warning message')
            logging.error('error message')
            logging.critical('critical message')
          灵活配置日志级别,日志格式与输出位置,用模块的basicConfig方法
            logging.basicConfig(level=logging.DEBUG,-----级别定为DEBUG
                                format='%(asctime)s %(filename)s[line:%(lineno)d'] %(levelname)s %(message)'--%()里面的就是变量,这几个不是必须的,是自己定的需要什么打印什么
                                            时间       文件             程序的行号     日志级别    记录内容  
                                datefmt='%a, %d %b %Y %H:%M:%S',--表asctime的时间格式
                                filename='test.log'---表filename,可用绝对路径
                                filemode='w')---filename模式,写模式日志不会打印屏幕而是文件里,但程序执行完重新启动就把之前的删了,可以用a模式
                         format的其它参数:
                             %(name)s:logger的名字
                             %(levelno)s:数字形式的日志级别
                             %(threadName)s:线程名,可能没有
            
            logging.debug('debug message')
            文件里打印的是fri,09 sep 2016 14:30:04 logging_module.py[line:10] DEBUG debug message
            logging.info('info message')
            logging.warning('warning message')
            logging.error('error message')
            logging.critical('critical message')
           这里运行脚本打印的日志就会生成一个test.log记录这些日志信息,这里日志级别的方法能直接调用模块basicConfig的格式化生成对应的日志到文件里
           这里面默认是打印在屏幕上的,如果加了filename就会写到文件里,只能有二种方式,但如果二个地方都要打印要如何做?
        3.logger :模块级别的函数
          import logging
          logger = logging.getLogger()---取出logger对象,这个对象是空的
          fh = logging.FileHandler('test.log')--文件输出流对象,文件对象
          ch = logging.StreamHandler()--屏幕对象
          formatter = logging.Formatter('%(asctime)s-%(name)s'-%(levelname)s-%(message)s')--格式对象
          fh.setFormatter(formatter)---文件打印的格式,setFormatter是fh对象的方法,把文件格式定好
          ch.setFormatter(formatter)---屏幕打印的格式
          logger.addHandler(fh)--把文件加进logger输出对象,文件又有自己的格式,添加进输出行为
          logger.addHandler(ch)---把屏幕对象也加进loggerll输出对象,屏幕也有自己的格式
          logger.setLevel(logging.DEBUG)---定日志级别
          logger.debug('123')
          logger.info('456')--下面这二个执行时屏幕与文件里都有日志
        4.日志级别
          要定级别,如果是info那比info高的都打印,比它低的就不打印            
          logger.setLevel(logging.DEBUG)--定级别或上面的level=logging.DEBUG

 

六、sys模块


 

  常用调用函数,与Python解释器进行交互的模块

        import sys
        *print(sys.argw):命令行参数list,第一个元素是程序本身路径,打印出解释器后所有的参数
                  >>>python test.py 如果这个脚本里有上传下载如果与python交互,可以从后面加上参数
                  >>>python test.py post path:告诉python下载路径,这些参数个数不定,这些参数如取用sys.argw
                 test.py
                  print(sys.argw)---执行这个脚本时打印(test.py post path)
                      if sys.argv[1]=='post'
                         post()---用写的上传函数,执行test.py这个脚本时根据后面的参数来控制这个函数使用什么功能
                         
        print(sys.exit(n)):退出程序,正常退出时exit(0),退出本脚本
        print(sys.version):获取python解释器版本信息
        print(sys.maxint):最大的int值
        *print(sys.path):返回模块的搜索路径,初始化使用PYTHONPATH环境变量的值
              若在这个变量里添加路径print(sys.path.append(C:\users))
        
        print(sys.platform):返回当前操作系统平台名称,作用:可以用这个做为跨平台判断,当它是win时可以调用os时写的路径就可以变了,这个程序就可以跨平台了
        print(sys.stdout.write('please'))--终端上标准输出
        print(sys.stdin.readline())

 

七、configparser模块


 

  用于生成和修改常见配置文档,当前模块在python3变为configparser

        (1)配置文件格式 
             [DEFAULT]
             ServerAliveInterval=45
             fotmat=5    
             [other]
              form=ie
             这是键值对的等式格式,如何生成?
             import configparser 
             config = configparser.ConfigParser()---操作文件句柄对象里面没数据,现在是空数据,下面进行给对象赋值
             config("DEFAULT") = {'ServerAliveInterval':'45','fotmat':'5'}---把DEFAULT做为键,后面的统一做为值
             config("other") = {'form':'ie'}
             with open('conf.ini','w',encoding='utf8') as f:
                    config.write(f)-----这时f写进的就是上面的配置文件
            print(config.sections())---取出键,other。注:这里的DEFAULT不行,它是默认的
            print(config.defaults())--能看到DEFAULT下面的二个值,生成一个元组的列表
            print('other' in config)--true
            print(config['other']['form'])---ie
            for key in config['other']:--这个值是字典,但如果是config则表示的是键,DEFAULT other
                print(key)---form  ServerAliveInterval fotmat--默认的也必须打出来
                
            如何修改?
             import configparser 
             config = configparser.ConfigParser()---文件句柄
             config.remove_section('other')    ---意思是删了other里的所有数据,但文件不能修改,就要加上后面进行修改
             config.write(open('f2','w'))---改为另一个文件就修改就解决了
             修改值
              config.set('other','form','de')---可直接改文件里的值
             删键下的对应的键
              config.remove_option('other','form')---可直接把文件里的键的键删除
            判断是否有对应字符串
             print(config.has_section('lili'))--flase

 

八、re模块:正则模块,进行模糊匹配


 

     (1)什么是正则表达式?
          用于匹配字符串的,跟列表元组没有关系         
     (2)匹配方法,字符串提供的方法是完全匹配,如果要模糊匹配如下:
          import re 
           元字符
               . :匹配单个字符,但不能代指换行符,如果字符串里有一个\换行符,它不行 'w..l'  --结果worl看到的是匹配到的全部
               ^ :以某内容开头的,结果是匹配到某内容
               $:以某某结尾 re.findall('a..x$','iemsjalex')--['alex']
               * :重复匹配,匹配前面0次或多次,{0,+oo}。re.findall('a.*li','fjkafalexli')
               + :重复匹配,匹配前面1次或多次 ab+  ---表a后有多个b才行,abbbb才是结果所以a也必须可有 
                    a+b---aaaab等
               ? :重复0次/1次
               {}:里面表匹配次数'a{5}b'--重复5次a haaaaab,'a{1,3}b'--可以是一个范围
               []:字符集,里面放的是字符的是或的关系,取消元字符的特殊功能,但(\ ^ -)例外
                  ret=re.findall('a[c,d]x','acx'):c或d  ---结果['a','c','d']
                  ret=re.findall('[a-z]','adx'):adx三个都会匹配上,特殊字符-例外
                  ret=re.findall('[w,*]','adx'):*不表示重复的功能,只表示*自己
               [^]:取反,[^t,x]--除了t,x.其它都是。^里面是全不是,不是绑定它紧后的
               |:或,分组()时的用  '(as)|3' --匹配的是as如果3放前面就匹配的是3
               ():分组,
                   print(re.search('(as)+','sdjkfasas').group())--asas
                   组名:?P<组名>
                   ret=re.search('?P<name>\d{3}','www123')
                   匹配出来的名字就是这个组名,可以取出这个组名
               \:1.反斜杠后边跟元字符去除特殊功能
                    \.:表示一个.
                    \\:re.findall(r'\\','adhfD\')---['\\']
                       为什么是二个\\,在re模块里是\\表一个\,但python也会有特殊字符,在python中也是\\是一个\,当\\传给python就是二个\\变为一个\
                  2.反斜杠后边跟普通字符实现特殊功能
                     \d:匹配任何十进制数,它相当于类[0-9]
                     \D:匹配任何非数字字符,相当于[^0-9]
                     \s:匹配任何空白字符。它相当于[ \t\n\r\f\v]
                     \S:匹配任何非空白字符,它相当于[^ \t\n\r\f\v]
                     \w:匹配任何字母数字字符,相当于[a-zA-Z0-9]
                       print(re.findall('\w','I am a LIST'))
                     \b:匹配一个特殊字符边界,也就是指单词和特殊字符间的位置,前后都是可以找到,\bI   I\b
                        print(re.findall('I','I am a LIST'))--会有二个I
                        print(re.findall(r'I\b','I am a LIST')),\b是查到I+特殊字符的边界,['I']
            ?:前面的* +等都是是贪婪匹配也是尽可能匹配,后面加?号使用其变成惰性匹配
               ret=re.findall('abc*?','abcccc')----ab,*最少识别c 0次所以c不要了
      (3)正则表达式的方法
          1.查找全部:re.findall(pattern,string,flag)--re.findall('w\w{2}l','hello world')--['worl']生成列表 
          2.search查找第一个,返回一个对象,对象可以调用一个group方法:ret=re.search('sb','fjaskdsbfasjksb') --返回结果是个对象不 内容 ,如何可应出内容
                                 print(ret.group())---就是满足条件的第一个结果sb,不是列表了              
          3.match():只在字符串开始匹配,同^,返回一个对象,可用group方法打印内容
               re.match('asd','asdfhdsasd')--是一个对象  ,re.match('asd','asdfhdsasd').group()              
          4.split()
            'asdf'.split('s')--字符串的这个方法是以s划分这个字符串
            
            ret=re.split('k','djksal')--['dj','sal']
            re.split('[k,s]','djksal')---这表示分二次,先以k来分,再用s来分第一次分出来的
         5.sub():表替换,三个参数,把替换内容的那个内容替换成哪个内容****
            re.sub('a..x','s..b','hfjasalexxdhf')--hfjass..bxdhf
         6.compile():先把规则编译成对象,用这个对象调用方法
            obj=re.compile('\.com')--里面是一个正则规则被编译
            obj=findall('magedu.com')
         7.finditer()---迭代器
            ret=re.finditer('\d','ds3sy4784a')
            print(next(ret).group())
     (4)计算器:
          用python实现一个计算器,实现加减乘除及拓号优先解析
          以下的数字是字符串:s='1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4/3)/(16-3*2))'
          1.匹配最里层的括号
            re.search('\('[^()]+\),s)--匹配到里面没有括号的括号
          2.写计算器
             
             import re
             def check(s):-检测表达式有没有错误
                 flag=True
                 if re.findall('[a-zA-Z]',s)
                     print('Invalid')--打印值
                     flag=False
                 return flag
             def format(s):
                 s1=s.replace(' ','')---空格变为空
                 s2=s.replace('++','+')
             def cal_mul_div(s):
                 re.search('\d+\.?\d*[*/]\d+\.?\d*')------('\d+\.?\d*    [*/]       \d+\.?\d*')
                                                        整与字浮数    这个表乘除
                  x,y=re.split('[*/]',ret)
                  if 
                  float(x)*float(y)
                  else
                  float(x)/float(y)
             if check(source):
                 strs=format(source)
                 while re.search('\('):
                     strs=re.search('\([^()]+\)',strs).group()
                     strs=cal_mul_div(strs):
                     strs=cal_add_sub(strs):加减函数

 

九、json模块


 

        (1)文件里只能写字符类型的,所以字典等类型不能直接写到文件
            dic={1:'ti',2:'di'}
            f=open('test','w')---会报错
            f.write(dic)---会报错,所以可以给dic做个str的转化   dic=str({1:'ti',2:'di'})
            data=f.read()
            print(eval(data)['1'])--取值
        (2)序列化:把对象(列表,字典,字符等)从内存中变成可存储或传输的过程称之为序列化,
          import json 
          dic={'name':'alex','age':'18'}
          data=json.dumps(dic)---把字典变为另一个自己存储的对象
          f=open('JSON_text','w')
          f.write(data)
          
          取这个文件里的内容,用另一个脚本实现
          f=open('JSON_text','r')
          data1=f.read(JSON_text)
          data2=json.loads(data1)----把序列化后的改回来
          print(data['name'])
          json只有这二个方法,支持所有的普通数据类型,比如字典、列表等,能与其它语言互通,但它不能把函数与类序列化
          那高级的数据类型序列化如何处理?用pickle,但它不能与其它语言互通
         上面是dumps与loads方法,那dump与load与它们是什么区别
          import json 
          dic={'name':'alex','age':'18'}
          data=json.dump(dic,f)--这里把dic序列化再f给write写进去了
          f.write(data)
          取出:
          f=open('JSON_text','r')

          data1=json.loads(data1,f)----把序列化后的改回来,把f读出来
          print(data['name'])

 

十、pickle模块---打把类与函数序列化


 

      (1)例
           import pickle
           def foo():
               print('ok')
           data=pickle.dumps(foo)
           f=open('PICKLE_text','w')
           f.write(data)
           f.close()
           
          拿出
          f=open('PICKLE_text','r')
          data2=f.read(PICKLE_text)
          data2=pickle.loads(data2)
          print(data2())

 

十一、shelve模块


 

  shalve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写.key必须为字符串

         (1)可以变化对象的多少
            import shelve
            f=shelve.open('SHELVE_text')
            f['info']={'name':'alex','age':'18'}---直接向文件写数据
            f['info1']={'other':'heigh'}
            data=f.get('info')
            print(data)
            data=f.get('info','name')
            print(data)

 

十二、xml模块(相当于json序列化)


          创建一个xml的文件xml_text
          <?xml version='1.0'?>
          <data>
              <country name='liechtenstein'>---标签  属性(name)
                  <rank updated='yes'>2</rank>
                  <year>2008</year>
              </country>
              <country name='panama'>
                  <rank updated='yes'>3</rank>
                  <year>2009</year>
              </country>--关闭
          xml_test.py----如何处理xml配置文件
          import xml.etree.ElementTree as ET
          tree= ET.parse('xml_test')
          root= tree.getroot()----结果最外层的data
          print(root.tag)
          遍历xml文档
          for child in root:
            print(child.tag,child.attrib)---结果:每个country里的属性name及值,country{'name':'liechtenstein'}
            for i in child:----遍历country里每个name里的标签
                print(i.tag,i.text)---结果:rank 2   year  8,包含上步结果
          只遍历year节点:
          for node in root.iter('year')---对year下的标签进行循环
              print(node.tag,nade.text)          
          修改:
             for node in root.iter('year'):
                new_year=int(node.text)+1---每个year的值加1,把每个标签的值拿出来         
                node.text=str(new_year)
                node.set('updated','yes')---改属性,把year加个属性
          最后写入数据,新生成一个文件
             tree.write('xmltext.xml')
         创建xml文件

 

十三、说明及实例


       (1)一个.py文件就称之为一个模块,就是对相关函数进行分组
       (2)分类:有三种
             python标准库:python自己定义的标准库
             第三方模块:非官方的
             应用程序自定义模块             
       (3)模块调用:为了来组织函数
           自己写的一个脚本,里有几个相关函数,cal.py
            def add(x,y)
                print x+y
                return x,y
           1.写另一个脚本bin.py如何调用cal
             import sys
             import cal  ---通过搜索路径找到cal后,实际上cal.py会把所有代码加载给cal这个变量,这个变量
             print(cal.add(1,2))-----这个cal要在当前路径下才能找到并调用?路径如何找的?
             print(sys.path)
             cal通过sys调当前路径bin从cal里找,并调用里面的函数
             模块里面的变量这个脚本里不能直接取出必须用cal这个变去引用print(cal.x)---1,所以里面的函数与变量都是要通过模块去调用
             当一个模块里有很多函数,只用其中几个?
                  如果只用cal是所有的函数都加载进去,当用到里面特定的 from cal import add
                  这时可以直接用方法不用cal来调用了,print(add(1+3)---不用cal来调用
           2. 若引用模块里多个函数
               from cal import add,del---这里Python只加载了这二个函数,用cal调用变量x也不行没有加载进来
                 可直接调用
           3.from cal import *---引用所有函数,下面可直接调用不同于直接import cal--这样会用cal.add来引用
                 如果本脚本里也自己定义了一个add的函数,下面直接调用会调谁的?
                 谁在代码前面就执行谁
        (4)包(packge):为了目录来组织模块,包目录下会有个_init_py,为了区分是包还是文件夹的,有这个就是包
              包怎么创建?右键---new--python package--创建一个包下面会自动生成_init_py,下面可以写很很多.py文件
              eg:
              web(包)
                  _init_py
                  
                  web2--也是包
                  _init_py
                  logger.py
              bin.py(与web一级)如何调用logger
              from web.web2 import logger(模块)  从包中调模块这时就可以调用模块了,但如何调用模块里的函数?
                logger.add()
                
            _init_py的作用:import web(包)---直接执行_init_py这个模块,跟模块不同import cal是把cal都是加载了而import web只执行_init_py,根下面的.py没用
       (5)例:ATM 一个项目有很多.py,
           ATM(普通目录)
           bin(包)
               _init_py
               bin.py--是程序的执行入口
                   from module import main
                   main.main()---会报错找不到logger,原因,执行这个脚本是在bin这个包下而不是module所以找不到,可以在上面用sys把ATM路径加进来,但易写死
           module(包)--逻辑相关代码
              _init_py
              logger.py
              main.py
                  import logger
                  def main():
                      logger.logging()
                                    
           conf(包)
              _init_py
              
              
              
               bin.py里面的正确写法?
                   加如相对路径
                   import os 
                   print(os.path.abspath(_file_))---_file_:打印当前程序的路径
                   print(os.path.dirname(os.path.abspath(_file_)))
                   BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(_file_))))---拿绝对路径
                   sys.path.attend(BASE_DIR)
       
       (6)if _name_=='_main_':让测试函数不执行
           hello.py
           def foo():
               print('hello')
            
           foo()----这就是测试这个函数能不能正常运行,当其它模块调用这个函数时会打印结果,而这个测试的也会打印
                    会引起问题,所以要加一个if _name_=='_main_',这时测试函数就不行执行了,除函数以外的代码都放这里
          if _name_=='_main_'        
          foo()
       (7)软件代码规范,目录的如何组织          
            Foo/
                bin/-------存放项目的一些可执行文件,也可以用script也行
                   foo---程序入口
            foo/---是一个包用于各功能函数,存放项目的所有源代码
                tests/---用于测试
                    _init_py
                    test_main.py
                _init_py
                main.py
            docs/---------存放一些文档
                conf.py
                abc.rst
            setup.py--------安装,部署,打包的脚本
            requirements.txt---存放软件依赖的外部Python包列表
            README-------项目说明文件(readme)
            
View Code

ATM实例

        思路:还款与购物是分开的  
     atm_test
         _init_.py
         bin
           _init_py
           atm.py--主逻辑
               #内容
                  import os 
                  import sys
                  base_dir=os.path.dirname(os.path.dirname(os.path.abspath(_file_)))
                  print(base_dir)
                  sys.path.append(base_dir)-----这步为了找atm_test,这样才能找到core里的main,包之间的引用要用到这个
                  from core import main---上能找到atm_test
                  if _name_ == '_main_'-----直接进main里去跑,这个atm本身不跑了
                     main.run()
           manage.py
      conf--------------可以放一些初值,定义字典列表等,存数据,是可配置的
          _init_py_
          setting.py
              #内容 
              import ...
              BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(_file_)))
              DATABASE={
                  'engine':'file_storage',
                  'name':'accounts'
                  'path':"%s/db"% BASE_DIR
              LOG_LEVEL=logging.INFO---日志级别,改配置可以现场调试
              LOG_TYPES={
                  'transaction':'transaction.log',---分日志文件
                  'access':'access.log',
              }
              TRANSACTION_TYPE={
                 'repay':{'action':'plus','interest':0}---支付,动作与利息
                 'withdray:{'action':'winue','interest':0.05}--转帐
                  
      core---主要程序逻辑都在这个目录里
          _init_.py
          accounts.py---用于从文件里加载和存储帐户数据
          auth.py   ----用于认证模块
              #内容 
              retry_count=0
              while user_data['is_authenticate'] is True and retry_count < 3:
                  
          db_hadler.py---数据库连接引擎
          logger.py---日志记录模块
               #内容 
               import logging 
               from conf import settings
               def logger(log_type)
                   logger = logging.getLogger(log_type)---loging对象
                   logger.setLevel(settings.LOG_LEVEL)---等级,是conf里写的一个方法,是一个变量
                   ch = logging.StreanmHandler()
                   ch.setLevel(settings.LOG_LEVEL)
                   ch=logging.StreamHandler)
                   ch.setLevel(settings.LOG_LEVEL)
                   log_file='%s/log/%s'%(setting.BASE_DIR,settings.LOG_TYPES[log_type])---日志文件路径,是个拼接路径
                   fh = logging.FileHandler(log_file)
                   fh.setLevel(setting.LOG_LEVEL)
                   formatter = logging.Formatter('%(asctime)s'-%(name)s-%(levelname)s)
                   ch.setFormatter(formatter)
                   fh.setFormatter(formatter)
                   logger.addHandler(ch)
                   logger.addHandler(fh)
                   returm logger
          main.py----主逻辑交互程序
               #内容
               user_data={
                   'account_id':None,
                   'is_authenticate':False,
                   'account_data':None 
                }
                import ...
               trans_logger=logger.logger('transaction')---去看logger.py,logger对象打印日志,登录的
               access_logger=logger.logger('access')---交易的
               def run()
                   acc_data = auth.acc_login(user_data,access_logger)---用户认证与日志打印,这二个只是变量,但在用的时候用的是其它模块里的函数通过前面的赋值实现,在上面赋值
                   if user_data['is_authenticate']:---这个字典的值是真还是假
                       user_data['account_data']= acc_data
                       interactive(user_data)
          transaction.py---记帐 还钱 取钱等所有与帐户金额相关信息
     db---用户数据存储的地方
          _init_.py 
          accout_sample.py--生成一个初始帐户数据
              #内容 
              import json 
              acc_dic = { -------卡号信息
                  'id':1234,
                  'password':'abc',
                  'credit' :15000,
                  'balance':15000,--余额
                  'enroll_data':'2016-01-02',
                  'expire_data':'2021-01-01',
                  'pay_day':22,--还款信息
                  'status':0,
             }
             data=json.dumps(acc_dic)
             f=open('123.json','w')
             f.wrint(data)---------------数据写入到json文件里,不同卡可以写不同文件里,不然他们不能同时改
              
          accounts--存各个用户数据,一个用户一个文件
               123.json---一个用户帐户示例
     log--日志目录
         _init_.py
         access.log---用户访问与操作日志
         transactions.log---所有交易日志
     shopping_mall---电子商城程序
         _init_.py
              
       总结: 1.login---包含auth()
              2.菜单(展示,选择)
View Code

 

十四、ssh客户端模块paramiko


 

详解:https://blog.csdn.net/Sxiaokun/article/details/124070120

 十五、python对话框


 

详解:https://blog.csdn.net/weixin_44289254/article/details/121043821

posted @ 2021-01-22 18:56  xiong_Dana  阅读(52)  评论(0编辑  收藏  举报