快速入手Python小册

前言

本博客主要是为了记录入门python的基础知识点,并作为个人的学习框架备忘。(需要一定的编程基础,其中过于基础的内容不做赘述。)

基础

python解析器: python使用最广泛的解析器就是用 C语言编写的,有些语言发明者搞出一些生硬的语言符号,这种语言一般完全不用理,没必要去进行学习,浪费生命,毕竟全世界有 七百种编程语言。

1.utf编码:utf码快速查询网站: https://unicode-table.com/en/4E1C/
encode编码就是各种字符组编成utf协议下映射的数据码文,decode解码就是将utf码文解析成易读的字符。 C语言中常见的就是ASCII码, python中utf-8能够兼容ascii码, utf-16不行,并且由于utf-16将数据码映射成十六进制为最小单位来存储,因此存在大小端的问题,这点在解码的时候要特别注意。几个常用函数如ord()函数将字符转化为对应的十六进制映射值。chr()函数将存储的数字映射值转化为字符数据。len()函数 将字符的长度输出。
utf-8在兼容性会比utf-16来得优秀, 用单字节存储映射数据,每个字节即可得到有效的映射所要表达的信息,因而不存在大小端的问题,utf-16主要是因为使用了双字节存储一个有效含义的数值,因此一个有效信息点被拆分成两部分来表达,因此,在decode的时候, 要区分大小端的问题。

Unicode符号范围UTF-8编码方式
0000 0000-0000 007F0xxxxxxx
0000 0080-0000 07FF110xxxxx 10xxxxxx
0000 0800-0000 FFFF1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
字符普通二进制UTF-16二进制UTF-16UTF-16BEUTF-16LE
$U+00240000 0000 0010 01000000 0000 0010 0100002400 24

utf-8, utf-16和ord()函数其实差不多,都是很直白地按顺序映射成数值,( 但是utf-16要注意到一个大小端的问题,), 相比之下, utf-8的映射显得更有考究一点,很多网页基本都是用 utf-8 来进行编码, 这样网页数据在传输,解码的时候,通用性更高。
2. 变量的产生: 和c/c++不同地方在于, python 中不需要对变量进行数据类型声明,在python中, 一旦有赋值的行为发生时,就会产生一个新的变量作用域,但是有可能变量的id是一样的, 比如变量的相互赋值a=b, 对于内存来说, 该过程就是产生一个变量的引用,而如果需要完全拷贝数据到一新的内存id上,则需要使用 copy模块, 进行浅拷贝以及深拷贝操作。
3. 在python中, __**__ 表示特殊内置变量 ,比如__name__变量会在每个脚本被执行的时候,会被赋值为__main__, 而如果只是作为包被调用, 则不会被赋值,所以,当我们要兼容二者的时候,会添加判断__name__是不是等于__main__的代码判断, _*** 表示非公开,私有变量。
4. 变量作用域: 变量一旦有赋值操作,即产生一个新的变量作用域, 函数内部的局部变量在想要使用全局变量, 需要使用 global关键字 来声明并引用变量名。python的命名空间主要遵循 LEGB的原则, 作用域范围由小到大分别是local(函数局部变量),enclosing(闭包,嵌套函数中变量), globals(全局变量), builtins(python解析器内置的变量). 如下例子, 对于解析器来说, 在闭包函数中做赋值操作时候,x 即被声明为局部变量(就不会找到上一层的范围中的变量,即使上一层有一个x变量可以引用), 引用的操作必须在赋值之后, 因为只有先赋值才能产生这个变量的作用域。

def enclosure():
    x=0
    def embed():
        x=x+9
        print(x)
        return x
    return embed
fun_p=enclosure()
fun_p()

File “trail.py”, line 40, in embed
x=x+9
UnboundLocalError: local variable ‘x’ referenced before assignment

5.从变量存储情况区分变量类型:可变类型,表示变量的值可被改变,地址id不变,常见的类型比如 list(列表, 立刀旁很像中括号吧,哈哈哈)。
不可变类型,表示变量的数值一旦变,地址也要变,原有地址存储的数据不能变。, 常见的是 tuple(元组, 一元硬币很像元括号吧), 当tuple只有一个元素的时候, 必须要编程为 tuple= (1,),也就是圆括号内必须带有进行分割, 这样表述免得和数学公式中括号的作用产生歧义,而需要声明字典变量的时候, 则通过使用花括号{ }来进行声明,( 字典的字的宝盖头刚好很像花括号,d1={“a”:1, “b”:2},哈哈哈), 字典通过pickle/json来转换为json 的字节流很方便.
4.1 数据如何索引, 列表,元组,字典 均用中括号,来写入索引,通过索引来引用其中的元素,字典传入key的字符串,则通过key来索引取得value值, dict.get("key") 获取字典元素, dict.pop("key")删除某个字典元素。
4.2 python中集合的妙用, set(list[]) 可以声明得到一个无序和无重复元素的集合, 在我们需要获取两个数据集合之间的交集以及并集的时候, 该数据类型特别方便。
6. 生成器:如果想使用海量数据存储空间, 又想节省空间, 即使用generator生成器,基本思想就是一边循环一边计算。, 借助for关键字内置的next函数进行遍历。当在函数内部使用yield(产出)关键字时, 我们可以将一个普通函数转换为generator函数, 每当函数执行到yield即返回一个迭代对象,下一次迭代的时候, 函数从 yield的下一个语句开始执行,以此得到一个可以实现迭代的函数对象。
7. 列表生成式,一种特别棒的语法:
list=[expression for i in range(1, 10)]
如何理解:语法中从 range()中得到的i的值,然后带入前面的表达式, 表达式计算的结果赋值给list 列表或者元组。
8. bytes关键字: bytes关键字将字符数据通过指定的encode编码形式如utf-8, 转化为的十六进制表达的转义字符表述, 转换后的数据如:
b’C\xe8\xaf\xad\xe8\xa8\x80\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x918\xe5\xb2\x81\xe4\xba\x86’, 转换后的数据通过bytes自带的decode方法,然后,指定转换编码形式(如utf-8),从而转换成可读形式字符。 注意: 转换后的结果头部以b字母开头, 其中的数据能用ascii码表示的,则继续使用ascii表示, 不能表示的则用转义字符表示。
6. 包的安装 : 包的安装没什么可讨论的, 主要是pip install keras==可以得到当前解析器可支持,可安装的版本,以及通过官方工具包的网站为 https://pypi.org, 通过下载whl文件,使用wheel安装工具进行安装.
7. 包的导入与创建: 模块包的目录下存在 init.py 文件,该文件用于控制包在import时的一些导入行为,确保导入的范围。init.py 中还有⼀个重要的变量,叫做 all,通过该变量来限制导入的元素范围。python中模块的导入, 如果把函数保存在 module.py, 则外部调用需要通过from module import function导入 ,module是文件名, function是函数方法名或者类名, (print(help(module_name))# 获取a_module的帮助文档。)。

模块基础:
Python中每⼀个文件都是⼀个模块, 文件名为模块名,使用import module 来导入模块,from xx import class 表示从xx文件中导入class类(函数,变量),
使用这种方法的话, 在python脚本中调用类的时候, 就可以避免去重复写模块名进行代码书写, module.class.a – > class.a, from xx import * 从xx模块文件引入所有公开的元素, reload 模块, 重载模块。
模块搜索路径:
• 程序所在路径
• 标准库安装路径
• 操作系统环境变量PYTHONPATH指向的路径
8.python中通过统一缩进来区别类,函数, 代码块的作用域,这点在编程中尤为方便, 顺便说一下, python中不支持 swtich语法。
9.python定义函数和makefile语法很像. 挺简洁。

#python空函数模板
def nop():
    pass  # 表示空占符,空语句,避免报错。
return None
# makefile函数定义
define fun
	@echo "makefile function"
endef
  1. 变量类型与变量地址: 通过id()函数查看变量的地址值,通过type()方法查看变量的类型。
  2. self 参数 : python类声明中的self参数,目的主要是为了 在函数方法中调用类内部声明的变量, 一般类内部的方法函数的第一个参数就是 self, 这点和C++中的this 指针的功能是一样的, 只是python这边都要求显式写出来。
  3. 嵌套类的使用: 无论是嵌套类还是非嵌套类, 类中的方法和元素一定要通过实例化之后,才能够进行调用, 如果要使用嵌套在内部的类的话,通过obj= out.inside() 先去实例化,再通过obj去调用insiden内部的方法函数, (通过@staticmethod修饰器来修饰,就可以不经过实例化 直接调用, 该修饰函数表示本身与对象无太多联系,不需要 self, cls等参数,只是放在类的内部进行管理. @classmethod修饰器修饰的时候, 表示只需要该方法只需要 cls参数, 不需要实例化,即可实现调用)
  4. 函数修饰器: python函数包含三种内置的函数装饰器, 如@classmethod,@staticmethod, @property, 当然我们也可以自己创造修饰器。
    使用装饰器语法:
    • 语法糖的写法
@function_name
def function():
	pass

@classmethod 修饰符对应的函数不需要实例化即可调用, 通过class_name.method()进行调用,不需要 self 参数,但第一个参数需要 cls 参数.
@staticmethod 不调用类内部的成员变量,和类本身无过多联系,只是为了便于管理, 只是放在类的声明中。
@property 将函数转换为属性变量,直接进行赋值操作。

便利的技巧

  1. ''' aaaa ''' 表示可以将多行字符包括在其中, 并包括换行符, 省得输入 /r 的转义字符,非常方便编写习惯,用于多行内容编写。 这点很像shell脚本中的语法.类似下面所示
<< EOF 
	input something....
EOF
  1. print(“value:%f”%(x**x)代码中 ** 表示指数幂计算。
    print字符串格式化, python中通过%(),将一个含有多个变量值的tuple传递给模板进行格式化输出, 除了该方法,python还提供了format()方法进行格式化输出。
print("name %s  %d"%("aaa"12))
  1. 方法/函数返回多个值的时候,如 return x,y时,其实,他返回的是一个 tuple 对象。
  2. 注意以下例子, 列表b和列表a的地址是一样的, 都指向最开始初始化那个对象,修改b就等于修改a,
    而如果要完全拷贝,应该使用copy函数复制.
a=[1]   初始化列表
b=a
print(a, b, id(a), id(b))
  1. python函数编程,支持可变参数,也就是说传入参数个数可变。
    def function(*element), 即等价于传入一个tuple/list对象到函数内部,可理解为C语言中一级指针的用法, 函数内使用的话, 则通过对element 进行for 取值实现调用。
    **kw 关键字参数 :支持传入 字典对象, 键值对参数,
    *argv 可变参数, 传入一个tuple,
    C/C++中, 指针数组的数组名赋值给 char **p 二级指针, 数组名则赋值给 char *p一级指针。(而二维数组的数组名 相当于数组指针数据类型)
  2. python slice功能,非常方便我们遍历列表
    比如 L[0:3], 从第0个开始取元素到第2个元素前停止。
    神奇的在于,支持取倒数的元素
    L[-3:-1], 倒数第三个到倒数第一个。
    通过strim函数实现递归,真的美观,
    易错:
    slice功能中,[x:y]第二个值y表示停止值, 只包含除了y索引指向的值。
    递归的核心思想, 就在于在一个基础上进行下一步类似的动作
strim(s)
if s[1]="  ", 等价于第零个。
     return strim(s[1])
elif s[-1]==" "   等价于倒数第一个,
     return trim s[-1],  除了最后一个为止,
  1. python中的for 可迭代的对象, 包括 字符串, 列表,元组, range(),dict默认迭代key, 如果要迭代 value, 要通过dict.value()去调用, 还支持一次性 遍历两个值。
    isinstance(a,Iterable), 判断是否可迭代。
  2. 在python中,Flase, 0, (), [],{}, 都会被视为假。逻辑运算包含 and ,or ,not,最便利的是成员运算符, in和 not in, 可以很快判断一个元素是否被包含。
  3. '中文'.encode('ascii') Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
    含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围.
  4. 得到十六进制的整数值的表达形式
    print("str:", hex(ord('东'))) str: 0x4e1c
    得到中文字符在 utf-8下,即通过一定的编码规则,得到编码值。
    print("str:", '东'.encode('utf-8')) str: b’\xe4\xb8\x9c‘
    得到中文字符在 utf-16下的存储形式,
    print("str:", '东'.encode('utf-16')) str: b’\xff\xfe\x1cN’
    其实等于第一种ord()方法得到的值,是将值进行十六进制存储进行展开,而此处utf-16由于芯片大小端问题,变成 \1c4e.
    注意: 输出中\xff\xfe 用来指示大小端的信息(UTF-16LE以FF FE代表,UTF-16BE以FE FF代表)
  5. python中很多内置函数随着解释器的运行便会创建起来, 可以进行直接调用。
    os.system 用来执行cmd 命令或者linux命令, 会开启一个cmd或者是shell进程作为执行命令的环境。
    python中的eval和exec,compile是十分有趣的函数。
    eval用来运行单个表达式, 并且返回表达式的计算值。
    exec可以用来执行代码段,通过""" 囊括整段代码。
    compile就是将将一个字符串编译为字节代码,然后通过eval或者exec来执行编译后的字节代码(目前很少使用,仅作文案记录。)
code_block = """
x = 1
y = 2
z = 3
sum = x + y + z 
print(sum)
"""
exec(code_block)

expr = "9+6"
val=eval(expr)
print(val)
  1. lambda [arg1 [,arg2,.....argn]]:expression 帮助函数更为简洁,但是, 并不会提高效率。
    lambda构建之后,lambda表达式会构建出一个以arg*为传入参数, expression计算得到的值为返回值的函数。
    注意 : expression是单表达式,不是代码块。

  2. python 中高阶函数技巧:python可以把函数对象名赋值给其他的变量,然后通过该变量进行函数调用, 类似C语言中的函数指针。
    Python 中内置的⾼阶函数:

    • map
      它接收⼀个函数 f 和⼀个 list
      并通过把函数 f 依次作⽤在 list 的每个元素上,得到⼀个新的 list 并返回。
    • filter
      filter()函数接收⼀个函数 f 和⼀个list
      这个函数 f 的作⽤是对每个元素进⾏判断,返回 True或 False
      根据判断结果过滤掉不符合条件的元素,返回由符合条件元素组成的新list。
    • reduce
      ⼀个函数 f,⼀个list,但⾏为和 map()不同
      reduce()传⼊的函数 f 必须接收两个参数
      reduce()对list的每个元素反复调⽤函数f,并返回最终结果值。
  3. python中的序列化&反序列化,分别是为了便于传输与存储,和跨平台进行数据交互。
    一般使用json 模块以及pickle模块,二者不存在什么较大的区别。
    序列化:
    • 变量从内存中变成可存储或传输的过程称之为序列化。
    • 在Python中叫pickling。
    • 在其他语⾔中也被称之为serialization, marshalling, flattening等等
    反序列化:
    • 把变量内容从序列化的对象重新读到内存⾥称之为反序列化, 即unpickling。

import pickle
dic={"k1":"v1", "k2":"v2"}
pickle_dic=pickle.dumps(dic)
print(pickle_dic)   # 序列化获得十六进制码。
print(pickle.loads(pickle_dic))  # 反序列化得到数据。
  1. python下的多线程是鸡肋, 推荐使用多进程, 有线程的需要的话,还是使用c++来编写代码比较合适。
    使用multiprocessing模块,可以模块自带的队列和管道的方式进行进程间通信。
  2. 正则表达式 :用于处理字符串的强大工具, 拥有独特的语法以及独立的处理引擎。
    re模块中 包含search, findAll, sub等方法。
    正则表达式使用贪婪与非贪婪匹配原则。
    贪婪原则会尽可能多地匹配地匹配字符, 非贪婪原则就是匹配到结果即结束。
    str=r'<html><body><h1>hello world<h1></body></html>'中的r表示该字符数据是rawdata(即原生数据),不进行任何转义, backslash表示转义作用(即反斜线字符)。

'*'表示匹配前一个字符重复 0 次到无限次,
'+'表示匹配前一个字符重复 1次到无限次,
'?'表示匹配前一个字符重复 0 次到1次。
*? 添加了?之后表示惰性匹配。
元字符比如 \d 表示数字字符匹配。

关于字符提取的正则表达式的示例代码如下:

import re
rd_str=r'<html><body><h1>hello world</h1></body></html>'
pattern=r'(?<=<h1>).+(?=</h1>)' # 匹配获取<h1>和</h1>之间的字符。
#(?<=[string]), 表示 得到在【string】之后的字符, 
#(?=[string]) 表示得到string 之前的字符串。
# . 表示匹配任意一个字符.
# ..表示匹配任意两个字符.
# + 表示匹配+符号的前面字符串,并且至少匹配到一个字符。
matcher=re.search(pattern, rd_str)
print(matcher.group()) # 提取到hello world
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值