Python基础知识笔记

=================Python基础知识相关笔记=====================

  1. / 表示浮点数除法,//表示整数除法,返回不大于结果的一个最大的整数。
  2. 操作系统的作用:
    1. 把硬件丑陋负责的接口隐藏起来,为应用程序提供良好接口
    2. 管理,调用进程,并且把进程之间对硬件的竞争变得有序化
  3. linux下的
  4. 多道技术:
    1. 产生背景:为了实现单CPU下的并发效果
    2. 分为两部分:
      1. 空间上的复用(必须实现硬件层面的隔离)
      2. 时间上的复用(复用CPU时间片)
        1. 什么时候切换?
          1. 正在执行的任务遇到阻塞
          2. 正在执行的任务运行时间过长
  5. 进程介绍
    1. 正在进行的一个过程或者说一个任务。而负责执行任务的则是cpu。
    2. 进程与程序的区别:
      1. 程序仅仅只是一堆代码而已,而进程指的是程序运行的过程。
      2. 同一个程序执行两次,那也是两个进程。 比如打开暴风影音。虽然是同一个软件,一个播放的是苍空井,一个播放的是饭岛爱。
    3. 并发与并行:
      1. 无论是并行还是并发,在用户看来都是同时运行的,不管是进程还是线程,都只是一个任务而已,真正干活的是cpu,cpu来做这些任务,而一个cpu同一时刻只能执行一个任务
      2. 并行:真正的同时运行,只是具备多个cpu才能实现并行
      3. 并发:伪并行,即看起来是同时运行。单个cpu+多道基数就可以实现并发(并行也属于并发)
    4. 同步与异步:
      1. 同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,知道收到返回消息才继续执行下去。
      2. 异步是指进行不需要一直等下去,而是继续执行下面的操作不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
      3. 举个例子:打电话就是同步通信,发短信就是异步通信。
    5.  系统的调用:
      1. linux:fork
      2. win:CreateProgress
    6. linux下的进程与windows下的区别:
      1. linux的进程有父子关系,是一种树形结构,windows没有这种关系
      2. linux创建新的进程需要copy 父进程的地址空间,wind下从最开始创建进程,两个进程之间就是不一样。
  6. 线程介绍:
    1. 在传统操作系统中,每个进程都有一个地址空间,而且默认就有一个控制线程。
    2. 进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是CPU上的执行单位。eg: 北京地铁是一个进程,地铁里的13号线是一个线程。
    3. 多线程指的是:在一个进程哩开启多个线程,简单的讲:如果多个任务公用一块地址空间,那么必须在一个进程内开启多个线程。
    4. 为何要用多线程:
      1. 多线程共享一个进程的地址空间
      2. 线程比进程更轻量级,线程比进程更容易撤销,在许多操作系统中,创建一个线程比创建一个进程要快10~100倍,在有大量线程需要动态和快速修改时,这一特性很有用
      3. 对于计算/CPU密集型的应用,多线程并不能提升性能,但对于I/O密集型应用,使用多线程会明显的提升速度(I/O密集型根本用不上多核优势)
      4. 在多CPU系统中,为了最大限度的利用多核,可以开启多个线程(比开进程开销要小的多)
  7. 异常处理
    1. 什么时候用异常处理 
      1. try...except 应该尽量少用,因为它本身就是你附加给你程序的一种异常处理的逻辑,与你的主要工作是没有关系的,这种东西加的多了,会导致你的代码可读性变差。只有在有些异常无法预知的情况下,才应该加上 try...except ,其他的逻辑错误应该尽量修正
  8. Socket
    1. 服务端
      import socket

      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET: internet网络;SOCK_STREAM: TCP 流式协议
      phone.bind(('127.0.0.1', 8081)) # 相当于插电话卡
      phone.listen(5) # 相当于开机
      print('starting')

      while True: # accept 连接循环

      conn, address = phone.accept() # 相当于接听电话
      print('client is coming ', address)

      while True: # 与conn的通讯循环
      try: # 针对windows下,当client断掉之后,会抛异常,需要加一个try except
      client_message = conn.recv(1024) # 读取客服端发过来的消息,收消息
      if not client_message: break # 在linux机器上,不会识别到client断掉的消息,会不断的收空消息。此时需要加一个判断。
      conn.send(client_message.upper()) # 回消息
      except Exception: # 捕捉通讯终端异常
      break
      conn.close() # 挂电话

      phone.close() # 关机
    2. 客户端 
      import socket

      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      phone.connect(('127.0.0.1', 8083)) # 连接服务器的地址

      while True:
      msg = input('>>>:').strip()
      if not msg: continue # 防止客户端发空,当是空消息时,继续输入
      phone.send(msg.encode('utf-8')) # 不能直接发字符串,需要发二进制的形式的文件
      back_message = phone.recv(1024) # 接受返回的消息
      print(back_message.decode('utf-8'))

      phone.close()
    3. 通过 socket 实现 远程执行命令:ls,pwd等
      1. 服务端
        mport socket
        import subprocess

        phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET: internet网络;SOCK_STREAM: TCP 流式协议
        phone.bind(('127.0.0.1', 8082))
        phone.listen(5)
        print('starting')

        while True:

        conn, address = phone.accept()
        print('client is coming ', address)

        while True:
        try:
        cmd = conn.recv(1024)
        print('receive')
        if not cmd: break
        res = subprocess.Popen(cmd.decode('utf-8'),shell=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)
        err = res.stderr.read()
        if err:
        cmd_res = err
        print('error')
        else:
        cmd_res = res.stdout.read()
        print('wokao cmd_res', cmd_res)
        conn.send(cmd_res)

        except Exception:
        break
        conn.close()

        phone.close()
      2. 客户端
        import socket

        phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        phone.connect(('127.0.0.1', 8082)) # 连接服务器的地址

        while True:
        cmd = input('>>>:').strip()
        if not cmd: continue # 防止客户端发空,当是空消息时,继续输入
        phone.send(cmd.encode('utf-8')) # 不能直接发字符串,需要发二进制的形式的文件
        cmd_res = phone.recv(1024) # 接受返回的消息
        print(cmd_res.decode('utf-8'))
        phone.close()
      3. 自定义表头解决粘包的问题。
        1. 只有TCP有粘包,UDP则没有粘包现象。所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。
        2. 服务端:
          import socket
          import subprocess
          import struct
          import json

          phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET: internet网络;SOCK_STREAM: TCP 流式协议
          phone.bind(('127.0.0.1', 8082))
          phone.listen(5)
          print('starting')

          while True:

          conn, address = phone.accept()
          print('client is coming ', address)

          while True:
          try:
          cmd = conn.recv(1024)
          print('receive')
          if not cmd: break
          res = subprocess.Popen(cmd.decode('utf-8'),shell=True,
          stdout=subprocess.PIPE,
          stderr=subprocess.PIPE)
          err = res.stderr.read()
          if err:
          cmd_res = err
          print('error')
          else:
          cmd_res = res.stdout.read()
          print('wokao cmd_res', cmd_res)
          # conn.send(struct.pack('i', len(cmd_res))) # 先发报头,报头 i 格式,会生成 int 类型的4个字节的报头
          head_dic = {'filename': None, 'hash': None, 'total_size': len(cmd_res)}
          head_json = json.dumps(head_dic)
          head_bytes = head_json.encode('utf-8')
          conn.send(struct.pack('i', len(head_bytes))) # 先发送报头的长度
          conn.send(head_bytes) # 再发送报头的bytes
          conn.send(cmd_res) # 最后发送真实是数据
          except Exception:
          break
          conn.close()

          phone.close()
        3. 客户端
          import socket
          import struct
          import json

          phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
          phone.connect(('127.0.0.1', 8082)) # 连接服务器的地址

          while True:
          cmd = input('>>>:').strip()
          if not cmd: continue # 防止客户端发空,当是空消息时,继续输入
          phone.send(cmd.encode('utf-8')) # 不能直接发字符串,需要发二进制的形式的文件

          # 先收报头的长度
          head_struct = phone.recv(4)
          head_len = struct.unpack('i', head_struct)[0]

          # 再收报头的bytes
          head_bytes = phone.recv(head_len)
          head_json = head_bytes.decode('utf-8')
          head_dic = json.loads(head_json)
          print(head_dic)

          # 最后根据报头里面的详细信息读取真实数据
          total_size = head_dic['total_size']

          receive_size = 0
          data = b''
          while receive_size < total_size:
          receive_data = phone.recv(1024)
          data += receive_data
          receive_size += len(receive_data)
          print(data.decode('utf-8'))

          phone.close()
  9. metaclass 元类
  10. 反射
    1. 定义: 通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
    2. 四个方法,适用于类和对象
      1. hasattr(object,name)        # 判断obj下是否有 name 方法
      2. getattr(object,name, defatult=None)   # getattr(p,'x','not exist')  判断p下面是否有x方法,如果没有则返回‘not exist’
        import ftpclient

        f1 = ftpclient.FtpClient('192.168.1.150')

        if hasattr(f1, 'get'): # 通过反射来判断 f1 中是否有get方法,如果有该方法则执行该方法
        func = getattr(f1, 'get') # 得到 f1 的 get方法,然后执行它
        func()
        else:
        print('没有该方法,执行其他操作')
      3. setattr(obj,name,value)      #setattr(p,'x', 12123232423)   # 给 obj 下的name  赋值
      4. delattr(x,y)    # delattr(Chinese,'country')      # 删除 Chinese 下的 country 属性
    3. class Ftpclient:

      def __init__(self,host):
      self.host = host
      print('ready to connecting')

      def run(self):
      while True:
      inp = input('---->请输入命令').strip()
      inp_l = inp.split()
      if hasattr(self, inp_l[0]):
      func = getattr(self, inp_l[0])
      func(inp_l)
      else:
      print('没有该命令')
      def get(self, arg):
      print('downloading file ', arg[1])

      def ls(self, arg):
      print('list the file', arg)

      f = Ftpclient('192.168.1.1')
      f.run()
  11. 模块:
    1. 定义:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。
    2. import
    3. 倒入模块干的事情:eg: import spam
      1. 产生新的名称空间
      2. 以新建的名称空间为全局名称空间,执行文件的代码执行文件的代码
      3. 拿到一个模块名spam,指向spam.py产生的名称空间。
      from ... import ....    from spam import money,read1
      1. 产生新的名称空间
      2. 以新建的名称空间为全局名称空间,执行文件的代码执行文件的代码
      3. 直接拿到的就是 spam.py 产生的名称空间中的名字。
      4. 优点:方便,不用加前缀。缺点:容易跟当前文件的名称空间冲突
      5. from xxx improt *  // 导入所有。
        1. __all__=[a,b,c]  //__all__ 用来控制 import * 来导入什么。
    4. import模块之后,模块的查找搜索路径:
      1. 先在内存中查找,再查找内置函数,最后再 sys.path 路径 
      2. 如果自己写的模块,无法import的时候,就需要操作 sys.path 路径
        1. import sys
        2. sys.path.appen('路径')  如果想优先级高: sys.path.insert(0,'路径')
        3. 这样就可以 import了。
  12. 包:
    1.  定义:包是一种通过使用:".模块名" 来组织python模块名称空间的方式。
      1. 无论是import形式还是 from...import形式,凡是在导入语句中(而不是在使用时)遇到带点的,都要第一时间提高警觉:这是关于包才有的导入语法
      2. 包是目录级别的(文件夹级),文件夹是用来组成py文件(包的本质就是一个包含__init__.py文件的目录)
  13. __name__控制python文件在不同用途下的行为:
    1. 当 XXX.py 当作脚本执行时,__name__ = ‘__main__’
    2. 当 XXX.py 当作模块导出时,__name__ = 模块名(XXX)
  14. 递归函数与二分法:
    1. 定义:在调用函数过程总,直接或间接地调用函数本身,这就是函数的递归调用。
    2. 应用:
      1. 二分法:
      2. # 使用递归的方式来生成斐波那契数列:1、1、2、3、5、8、13、21、34。。。。。
        # 格式如此:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
        # 数列从第3项开始,每一项都等于前两项之和。

        def recur_fibo(n):
        if n <=1 :
        return n
        else:
        return (recur_fibo(n-1) + recur_fibo(n-2))

        nterms = int(input('请输出几项'))
        if nterms <= 0:
        print('请输入正数')
        else:
        print('开始输出斐波那契数列')
        for i in range(1,nterms+1):
        print(recur_fibo(i))
      3. list_a = [1,99,88,77,49,102,53,4,9,80,89]
        list_sorted = sorted(list_a)

        def search(find_num, li):
        if len(li) == 0:
        print('not exits')
        return
        mid_index = len(li) // 2
        mid_num = li[mid_index]
        if find_num > mid_num:
        li = li[mid_index+1:] # 给li 重新赋值一次。
        print(li)
        search(find_num, li)

        elif find_num < mid_num:
        li = li[:mid_index]
        print(li)
        search(find_num,li)
        else:
        print('find it')
        search(0,list_sorted)
  15. 面向过程的程序设计:是一种流水线式的编程思路,是机械式的
    1. 优点:程序的结构清晰,可以把负责的问题简单化
    2. 缺点:扩展性差
    3. 应用场景:linux内核,git,httpd
  16. 名称空间与作用域
    1. 内置名称空间
    2. 全局名称公交
    3. 局部名称空间
    4. 内置和全局名称空间属于全局范围,全局作用域:全局有效,在任何位置都能被访问到,除非被删除(del),否则存活到文件执行结束
    5. 局部名称空间,局部作用域:局部有效,只能在函数内部被访问到,在函数执行结束后,就释放了。
  17.  函数对象(第一类对象):
    1. 函数可以被当数据来传递
    2. 可以被引用
    3. 可以当作参数传递给另外一个函数
    4. 可以作为函数的返回值
    5. 可以当作容器类型的元素
  18. 内置函数
    1. 匿名函数:lambda  只使用一次的函数就用匿名函数
      1. def func(x,y): return x+y 就是有名函数
      2. lambda x,y: x+y
    2. max,min, sorted, zip
      1. def func(x,y):
        return x + y

        # 等同于 func
        lambda x, y: x+y

        #
        salary = {
        'egon': 3000,
        'alex': 100000,
        'better': 20000000,
        'hello': 2000
        }

        print(max(salary)) # 默认按照key值进行比较,最大的值输出来
        print(max(salary, key=lambda x: salary[x])) # 按照 value值进行排序,将最大的 key 值输出来
        print(min(salary, key=lambda x: salary[x]))
        print(sorted(salary, key=lambda x: salary[x])) # 按照value值从小到大进行排序,然后输出 key值。
        print(sorted(salary, key=lambda x: salary[x], reverse=True)) # 按照value值从大到小进行排序,然后输出 key值。
        # res = zip(salary.values(), salary.keys())  # 生成元组对象。
        # print(list(res))
    3. map, reduce, filter
      1. # map 映射函数,列表+一个 SB 后缀
        #
        l = ['alex', 'wupeiqi', 'yuanhao']

        g = map(lambda x: x + 'SB', l)
        print(list(g))

        # num元素各自平方 一下
        num = [2, 4, 9 ,10]

        n = map(lambda x: x**2, num)
        print(list(n))


        # reduce 合并函数(累积函数),在python2里面,是作为内置函数存在的,在python3里面,则放在了 functools 里面。应用场景:hadloop 大数据
        from functools import reduce
        numlist = [1,3,5,7,9]
        # 求所有元素相加只和
        sum = reduce(lambda x,y: x+y, numlist, 10) # 第一个参数是个函数:lambad,第二个参数是一个迭代器。
        # 第三个参数是初始值,如果默认没有的话,则为:1+3+5+7+9。如果有初始值的话,则为:10+1+3+5+7+9
        print(sum)
        # filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
        # 该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,
        # 最后将返回 True 的元素放到新列表中

        # 应用1: 过滤出 以SB为结尾的 列表元素
        l = ['w_SB', 'b_SB', 'c', 'd_SB']

        g = filter(lambda x: x.endswith('SB'), l)
        print(list(g))

        # 应用2:过滤出列表中所有的奇数

        l1 = [1,2,3,4,5,6,7,8]

        def is_odd(n):
        return n % 2 == 1

        new_list = filter(is_odd, l1)

        print(list(new_list))

        # 应用3:过滤出1~100中平方根是整数的数:

        import math

        def is_sqr(x):
        return math.sqrt(x) %1 == 0

        sqr = filter(is_sqr, range(1,101))

        print(list(sqr))
  19. 生成器
    1. 概念:只要函数体包含yield关键字,该函数就是生成器函数。生成器函数就是迭代器
    2. yield的功能:
      1. 相当于为函数封装好__iter__和__next__
      2. return只能返回一次值,函数就终止了,而yield能返回多次值,每次返回都会将函数暂停,下一次next会从上一次暂停的位置继续执行
    3.  yield的两种形式
      1. 语句形式:yield 1
      2. 表达式形式:x = yield,下面是表达式形式的使用方法

        1. def eater(name):
          print(' %s ready to eat' % name)
          while True:
          food = yield
          print('%s start to eat %s' % (name, food))

          g = eater('zhang')
          next(g) # next() 就相当于 g.send(None),执行 g.send() 之前必须next(g)一次,或者执行 g.send(None)一次。
          g.send('wo')


          # 可以尝试用一个装饰器,在执行eater() 之前,就初始化,执行了,g.send(None),如下所示:

          def init(func):

          def wrapper(*args, **kwargs):
          g = func(*args,**kwargs)
          next(g)
          return g
          return wrapper

          @init
          def eater(name):
          print('%s ready to eat' % name)
          while True:
          food = yield
          print('%s start to eat %s' % (name, food))

          g = eater('zhang') # 输出:zhang ready to eat
          g.send('shit') # 输出:zhang start to eat shit
          print(g.send('shit2')) # 会输出 None ,原因是 yield 后面没有值,如果想要输出值, yield后面需要有值。

          # 如果每次打印上了什么菜。就需要在yield后面加上数据
          def init(func):

          def wrapper(*args, **kwargs):
          g = func(*args,**kwargs)
          next(g)
          return g
          return wrapper

          @init
          def eater(name):
          print('%s ready to eat' % name)
          foodlist = []
          while True:
          food = yield foodlist
          foodlist.append(food)
          print('%s start to eat %s' % (name, food))



          g = eater('zhang') # 输出:zhang ready to eat

          #g.send 表示先把shit 赋值给yield,然后由yield再赋值给 food
          g.send('shit') # 输出:zhang start to eat shit
          print(g.send('shit2')) # 会输出 None ,原因是 yield 后面没有值,如果想要输出值, yield后面需要有值。
          print(g.send('shit3'))
    4. # 通过yeild来实现  【grep -rl 'python' /root 】这个linux命令,意思是:通过递归的方式 找到root目录下所有包含 python 内容的文件名


      # os.walk 方法是用来遍历路径的。 r 参数表示用路径用"原生字符串"进行遍历 。意思是"\" python 解释器就不要处理了,r=raw-string。
      # 在windows环境需要用 r。在linux下则不需要了
      import os

      # address = os.walk(r'/Users/zhangzhihui/Desktop/Python/Basic/A')

      #
      # def search(search_path):
      # address = os.walk(search_path)
      # for par_dir, _, files in address: # 这里有三个值,【par_dir, _, files】par_dir 表示父目录,
      # # _表示子目录(不需要子目录的话,用_表示就可以了),files表示子文件
      # for file in files:
      # file_abs_path = par_dir + '/' + file
      # print(file_abs_path)
      #
      # search('/Users/zhangzhihui/Desktop/Python/Basic/A')

      # 上面的方法只能search一次,如果需要多次执行 search的话,就需要用 yield 方法了,因为yield生成器函数每次都需要执行一次 next(),
      # 否则就会报错,所以需要加一个装饰器,让装饰器来每次执行一下 next()方法。 如下代码所示:
      def init(func):
      def wrapper(*args, **kwargs):
      res = func(*args, **kwargs)
      next(res)
      return res
      return wrapper

      # @init
      # def search():
      # while True:
      # search_path = yield
      # address = os.walk(search_path)
      # for par_dir, _, files in address:
      # print(par_dir)
      # for file in files:
      # file_abs_path = par_dir + '/' + file
      # print(file_abs_path)

      # g = search() #search()就是一个生成器
      # g.send('/Users/zhangzhihui/Desktop/Python/Basic') # 此时会将 该目录下的所有文件都遍历出来

      # 写一个open函数,源源不断的读取传过来的路径,然后打开路径下的文件。
      # @init
      # def opener():
      # while True:
      # file_abs_path = yield # 生成器 send一次,会传一次值给 yield 然后赋值给 file_abs_path
      # print(file_abs_path)
      # # with open(file_abs_path,encoding='utf-8') as f:
      # # pass
      #
      # o = opener()
      # o.send('/Users/zhangzhihui/Desktop/Python/Basic/A')
      # o.send('/Users/zhangzhihui/Desktop/Python')
  20. 迭代器
    1. 概念:重复+上一次迭代的结果为下一次迭代的初始值。重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果是下一次迭代的初始值
    2. 为什么要有迭代器:
      1. 对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式
    3. 迭代器优缺点:
      1. 优点:提供一种不依赖索引的迭代方式;节省内存
      2. 缺点:无法获取长度;一次性
  21. 装饰器
    1. 定义:修饰别人的工具,修饰指的是:添加功能;工具指的是:函数。
      1. 装饰器本身是任何可调用的对象(加括号就可以执行的函数)
      2. 被装饰得对象也可以是任意可调用的对象
    2. 为什么要用装饰器:
      1. 开发封闭原则:对修改是封闭的,对扩展是开放的。
      2. 装饰器就是为了在不修改源代码以及调用方式的前提下,为其添加新功能
    3. 装饰器的格式就是一个:闭包函数
    4. 应用:
      1. import time

        #定义一个函数,延迟3秒 打印出:I love you。如果在不修改 index的情况下,调用index时,可以打印出运行时间,此时就需要运用到装饰器。
        # def index(a):
        # time.sleep(3)
        # print ('I love you')
        # index()

        # 定一个装饰器(装饰器就是一个函数,格式相当于闭包函数的格式)
        def timer(func):
        def wrapper():
        start_time = time.time()
        func()
        end_time = time.time()
        run_time = end_time-start_time
        print (run_time)
        return wrapper

        @timer # @timer 就是装饰器的调用方法,相当于 index = timer(index)
        def index():
        time.sleep(3)
        print ('I love you')

        #此时直接调用 index 函数时,就可以在不修改index的情况下,为其添加新功能。
        index()
  22. 闭包函数
    • 定义:在函数内部使用,包含对外部作用域而非全局作用域的引用。该内部函数就称为:闭包函数。
    • eg:f2() 函数就被称为闭包函数
      def f1():
      x = 2
      def f2():
      print (x)
      return f2

      f = f1()
      f()
    • 闭包函数的应用:惰性计算,想什么时候用的时候,直接 "函数名+()" 就可执行:baidu()
    • # 在函数内部使用,包含对外部作用域而非全局作用域的引用
      # get() 函数包含了对外部作用域的引用:url
      from urllib import urlopen

      def index(url):

      def get():
      res = urlopen(url).read()
      return res

      return get

      baidu = index('http://www.baidu.com')
      print (baidu())

      # 查看闭包函数引用的值,只要是闭包函数就有一个:__closure__ .它的结果是一个 cell。

      url = baidu.__closure__[0].cell_contents
      print (url)

 

 

 

=================第三天相关笔记=====================

  1. 函数
    • 按照有参和无参可以将函数调用分两种:有参函数 和 无餐函数。
      • foo() #定义时无参,调用时也无需传入参数
      • bar('egon') #定义时有参,调用时也必须有参数
    • 在python中函数分为:内置函数和自定义函数
    • 定义函数的三种形式
      • 无参数函数:如果函数的功能仅仅只是执行一些操作而已,就定义成无参函数,无参函数通常都没有返回值
      • 定义有参函数:函数的功能的执行依赖于外部传入的参数,有参函数通常都有返回值
      • 空函数
    • 函数的使用包含两个阶段:定义阶段和使用阶段
    • 为什么要定义函数?:
      • 先定义后使用,如果没有定义而直接使用,就相当于引用了一个不存在的变量名

=================第二天相关笔记=====================

  1. String 字符串
    • name = “zhangZhiHUI”
      • v = name.casefold()  #将所有的字符都变成小写,包括德语等其他语言,
      • v = name.lower() # 只将英文字符变成小写 
      • v = name.upper() # 将所有的字母都大写
      • v = name.swapcase() # 将所有的字符进行大小写转换。
      • v = name.center(20,’@‘) #参数1表示总长度。参数2: 表示空白处填充的字符(长度为1)
      • v = name.count('Z’) #表示传入值在字符串中出现的次数。
      • v = name.count(‘Z’,2) #第一个参数表示:起始位置(索引)。
      • v = name.count(‘Z’,2,5) #第二个参数表示:结束位置(索引)。
      • v = name.startswith(‘zh’) # 是否以xx开头
      • v = name.endwith(‘UI’) #是否以xx结尾
      • v = name.find(‘a’) # 找字母a,如果找到,返回字母a所在字符串中的位置,找不到返回 -1
      • v = name.index(‘a’) #找字母a,如果找到,返回字母a所在字符串中的位置,找不到会报错~ 建议用find。
      • v = name.isidentifier() #是否是标志符,eg:class 
      • v = name.isdecimal() #判断是否是数字,eg: ‘123'
      • v = name.isdigit() #判断是否是数字:eg:’123’ 2⃣️ 都能判断
      • v = name.isnumeric() #判断是否是数字:eg:’123’,’二’,2⃣️
      • v = name.isalnum() #判断是否是字母加数字。
      • v = name.isalpha() #判断是否是字母
    • 字符串的格式化
      • name = "我是:%s;年龄:%s;性别:%s"
      • name = "我是:{0};年龄:{1};性别:{2}"
      • v = name.format(“zhang",19,'都行')
      • name = "我是:{name};年龄:{age};性别:{gender}"
      • v = name.format(name='李杰',age=19,gender='随意')
      • name = "我是:{name};年龄:{age};性别:{gender}"
      • v = name.format_map({'name':"李杰",'age':19,'gender':'中'})
    • 字符串的连接
      • name = ‘alex’
      • v = ‘_’.join(name) #输出为:a_l_e_x
    • 字符串的替换
      • name = ‘zhangsbzhihueisbgoushi’
      • v = name.replace(’SB’,’love’) #将SB替换成love
      • v = name.replace(’SB’,’love’,1) #将第一个SB替换成love
  2. List 列表 可变类型
    • 扩展原列表
      • user_list = ['zhang','zhihui','alex']
      • user_list.extend(['zhao','yiwei','zhang’])
      • user_list = ['zhang','zhihui',’alex’,'zhao','yiwei','zhang’]
      • user_list.index(‘zhang’) 。查到的话,返回索引值。查不到的话,报错。
      • user_list.reverse() #整个列表的反转
      • user_list.sort() #整个列表按照ascii码排序eg:a~z 从小到大
      • user_list.sort(reverse=True) 从大到小进行排序
  3. Tuple 元组,不可被修改的列表,不可变类型
    • user_tuple = (‘alex’,’eric’,’zhang’,[‘a’,’b’,’c’],
    • tuple的子元素不可以被变更,但孙子元素是可以被变更的。
    • 元祖的最后,需要加一个逗号
  4. Dict 字典--可变类型,字典可以嵌套;字典的key必须是不可变类型
    •  深浅copy
    • dic.get(‘key’) #通过key来获取指定的value值。如果key不存在,则返回None
    • v=dic.pop(‘key’) #删除key和key对应的value,并将value值返回给v
    • v=dic.popitem() #随机删除键值对,并将键值对返回给v
    • dic.setdefault(‘key’,’value) #如果字典中不存在key值,则将key,value增加到字典中。如果存在key值,则不进行任何操作。
    • dic.update({‘k1’:’v1,’k5’:’v5}) #批量修改和更新,如果有对应的key,则update,如果没有对应的key,则新增入字典。
    • dic = dict.fromkeys([‘k1’,’k2’,’k3’],123) #新建一个所有value都等于123的字典
  5. Set 集合 --不可重复的列表,可变类型
    • s1 = {"alex",'eric','tony','李泉','李泉11’}
    • s2 = {"alex",'eric','tony','刘一’}
    • v = s1.difference(s2) # 表示s1中存在而s2中不存在的元素
    • s1.difference_update(s2) #表示s1中存在而s2中不存在的值。先将s1清空,在将值重新付值到s1中 。v={'李泉','李泉11’}
    • v = s1.symmetric_difference(s2) #去除s1和s2共有的值,返回给v
    • v = s1.intersection(s2) #s1和s2的交集
    • v = s1.union(s2) #s1和s2的并集
    • s1.discard(‘alex’) #将alex元素移除
    • s1.update({‘a’,’b’,’c’}) #重复的值不做操作,不一样的值添加进s1
  6. Enumerate枚举,会额外声称一列有序的数字
    • user_list = ['zhang','zhi','hui','zhaoyiwei’]
      • for i,ele in enumerate(user_list,1): #参数1表示从数字1开始输出有序的数字
      • print(i,ele)
      • 输出结果:
        1 zhang
        2 zhi
        3 hui
  7. 其他
    • range()函数在2.7里面,会立即生成所有在范围内的数字,缺点,当数值范围较大时,会引起内存Crash。而在3.x里面,不会立即生成,只有循环迭代时,才会一个一个生成,
      • 输出10~0
      • for i in range(10,0,-1)
      • 输出 1,3,5,7,9
      • for i in range(1,10,2)

 

 

 

=================第一天相关笔记=====================

  1. Python种类和其他语言的对比
    • CPython:代码 -> C 字节码 -> 机器码 (一行一行进行编译执行)
    • PyPy:代码 -> C 字节码 -> 机器码 全部转换完 再执行->执行
    • 其他Python(Jython): 代码 -> 其他字节码 -> 机器码
  2. 字符编码:
    • ascii :8位二进制数来表示 256种可能的字符,00000000 2**8=256
    • unicode 万国码: 至少两个字节起,占用内存空间比较大。
    • utf-8 :弹性存储,是对万国码的压缩。中文占三个字节。00000000 00000000 00000000
    • gbk,gb2312:中文需要两个字节。00000000 00000000  
  3. 变量
    • 字母
    • 数字(变量不能以数字开头)
    • 下划线
    • 不能使用关键字来命名变量
    • 变量名需要设置一个有意义的,可以通过下划线方式。eg:usr_info
  4. Python数据类型
    • 布尔值:
      • 数字:只有数字0是 False,其他都是 True
      • 字符串:只有""是 False,其他的都是 True,包括" "。有空格也表示 True
  5. 占位符
    • 相关格式:
      • name = '我叫: %s,性别: %s,年龄: %d' % ('张志辉', '男', 18)
  6. 运算符
    • and or 运算符
      • 1 == 1 and 1 > 2 or 1 == 4  False 如果遇到and,左侧正确再继续向后看,如果右侧也正确,则就表示正确。or后面的就不用看了
      • 1 == 1 or 1 > 2 and 1 == 4  True   从左到右。如果遇到or,如果左侧是True,右侧就不用看了,直接忽略,打印出来是True。
      • 原理:and 和 or 优先级相等,
  7. String相关操作
    • 移除空格和换行符
      • val = ' alex ' 。
        • val.strip()   #移除左右空格,包括回车换行。
        • val.lstrip()  #移除左侧空格,rstrip()表示移除右侧空格
    • 分割
      • val = 'zhang|zhihui|9|10'
        • val.splict('|')  #通过 | 来分隔,分隔出list:['zhang', 'zhihui', '9','10']
        • val.splict('|',1)  #表示只分隔左侧第一个|,分隔出list:['zhang', 'zhihui|9|10']。如是2,则表示分隔左侧两个 |
    • 长度&索引
      • len(val)  长度
      • val[0]     索引
    • 切片
      • name = 'zhangzhihui'  
      • name[0:5]  #打印索引 0,1,2,3,4 五个字符。
      • name[0:5:2]  #打印索引 0,2,4 三个字符,步长为2.
  8. List 列表
    • 删除
      • n = [ 'zhang', 'zhi', 'hui' ]
      • v = n.remove('zhi')  #根据value删除
      • v = del(n[0])   #按照索引删除
    • 更新
      • n = [ 'zhang', 'zhi', 'hui' ]
      • n[1] = 'zhao'
  9. 字典
    • 创建
      • 1 user = {
        2     'name': 'zhiHui',
        3     'age': 18,
        4     'gender': 'male'
        5 }
    • 增加&更新
      • user['age'] = 34         #如果没有该key,则新增;如果有该key,则更新。
    • 索引
      • n = user['name']       #可以通过key获取值。获取值为:zhiHui
    • 删除
      • del user['name']       #通过key来删除
    • 循环
      • # 打印字典里的key
        for item in val.keys():
            print(item)
        
        # 打印字典里的values
        for item in val.values():
            print(item)
        
        # 打印键值对
        for key, value in val.items():
            print(key, value)
    • 相互嵌套
      •  1 user_dict = {
         2     'k1': 'value1',
         3     'k2': {'kk1': 'vv1', 'kk2': 'vv2', 'kk3': 'vv3'},
         4     'k3': 123,
         5     'k4': ['alex', 'eric', ['a', 'b', 'c'], '张志辉', {'k11': 'v11'}]
         6 }
         7 
         8 # K4下的list列表中append一个元素
         9 user_dict['k4'][2].append('dog')
        10 print(user_dict)
        11 
        12 # 通过索引得到其中的一个元素的value
        13 n = user_dict['k4'][4]['k11']
        14 print(n)
        15 
        16 # 通过key更新 value
        17 user_dict['k2']['kk1'] = 'zhang'
        18 print(user_dict)
        19 
        20 # 插入key and value
        21 user_dict['k5'] = 7899
        22 print(user_dict)

 

posted on 2017-04-24 20:18  张志辉99  阅读(202)  评论(0编辑  收藏  举报