Python基础 Acemyzoe

Python基础

三个基本概念

  1. 结构化(函数、模块、包)
  2. 面向对象(类及派生类、重载)
  3. 虚拟环境(版本管理、环境隔离)

四类基本操作

  1. 数据操作(各种数据类型的操作)
  2. 文件操作(文件打开读写关闭等操作)
  3. 模块操作(导入使用、模块查寻等操作)
  4. 并发操作(进程与线程、锁/信号号/安全队列等)

五大基本语句

  1. (变量、对象、赋值运算符)
  2. 输入输出语句(print, input函数)
  3. 条件判断语句(if-elif-else语句)
  4. 循环语句(遍历循环for-in-else、条件循环while-else、break/continue)
  5. 异常处理语句(try-except-else-finally)

六种数据类型

  1. 数字类型(int,bool,float,complex)
  2. 字符串 (str)
  3. 列表(list)
  4. 元组(tuple)
  5. 字典(dict)
  6. 集合(set)

Some issue

  • 超时错误提示:pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='pypi.tuna.tsinghua.edu.cn', port=443): Read timed out.
    pip  --default-timeout=100 install Pillow
    直接download whl文件
    

注释规范

变量、方法、类的命名规则

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
__Title__ = '变量函数类命名'
__Author__ = 'ace'
__Author_email__ ='acemyzoe@outlook.com'
__Time__ = '2018/1/22'
"""

# 变量命名总结:
# 1.单下划线开头变量:protected
# 2.双下划线开头变量:private
# 3.双下划线开头,双下划线结尾:系统内置变量

"""
单下划线开头变量
_xxx,单下划线开头的变量,标明是一个受保护(protected)的变量,原则上不允许直接访问,但外部类还是可以访问到这个变量。
这只是程序员之间的一个约定,用于警告说明这是一个私有变量,外部类不要去访问它。
print(stu._name) 当要输入_name时,不会进行_name的提示
print(stu.age) 当要显示age时,会进行age的提示
"""

class Student:
    def __init__(self, name, sex):
        self._name = name
        self.sex = sex

stu = Student('ace', 'Male')
print(stu._name) # 单下划线protected的变量,原则上不允许直接访问 输出:ace
print(stu.sex) # age可以直接访问 输出:Male

"""
双下划线开头
__xxx,双下划线开头的,表示的是私有类型(private)的变量。
只能是允许这个类本身进行访问了, 连子类也不可以.
用于命名一个类属性(类变量),调用时名字被改变
(在类Student内部,__name变成_Student__name,如 self._Student__name)
双下划线开头的实例变量是不是一定不能从外部访问呢?其实也不是。仍然可以通过_Student__name来访问__name变量:
"""

class Person:
    def __init__(self, name):
        self.__name = name  

per = Person('ace')
print(per._Person__name) # 输出ace 但是无法直接访问__name

"""
双下划线开头,并且以双下划线结尾
__xxx__,以双下划线开头,并且以双下划线结尾的,是内置变量.
内置变量是可以直接访问的,不是 private 变量,如__init__,__import__或是__file__。
★不要自己定义这类变量
xxx_,单下划线结尾的变量一般只是为了避免与 Python 关键字的命名冲突
USER_CONSTANT,大写加下划线,对于不会发生改变的全局变量,使用大写加下划线
"""

# 函数命名总结:
# 1.私有方法:小写和一个前导下划线
# 2.特殊方法(魔术方法):小写和两个前导下划线,两个后置下划线
# 3.函数参数:小写和下划线,缺省值等号两边无空格

"""
函数
总体而言应该使用,小写和下划线

私有方法 : 小写和一个前导下划线
这里和私有变量一样,并不是真正的私有访问权限。
同时也应该注意一般函数不要使用两个前导下划线(当遇到两个前导下划线时,Python 的名称改编特性将发挥作用)。特殊函数后面会提及。

#特殊方法 : 小写和两个前导下划线,两个后置下划线
#这种风格只应用于特殊函数,比如操作符重载等。

#函数参数 : 小写和下划线,缺省值等号两边无空格

"""

# 私有方法
class PrivateCase:
    @staticmethod
    def _secrete():
        print(r"Don't test me") 

priC = PrivateCase()
priC._secrete() # _secrete为protected member

# 特殊方法(魔术方法)
def __add__(self, other):
    return int.__add__(other)

# 函数参数
def connect(self, user=None):
    self._user = user

"""
★类名称命名:
类总是使用驼峰格式命名,即所有单词首字母大写其余字母小写。
类名应该简明,精确,并足以从中理解类所完成的工作。
常见的一个方法是使用表示其类型或者特性的后缀,例如:SQLEngine ,MimeTypes
对于基类而言,可以使用一个 Base 或者 Abstract 前缀
不要滥用 *args 和 **kwargs,可能会破坏函数的健壮性
"""

Dict

  • 字典中如何根据value值取对应的key值

    dicxx = {'a':'001', 'b':'002'}
    #1
    list(dicxx.keys())[list(dicxx.values()).index("001")] #=> a
    #2
    def get_keys(d, value):
        return [k for k,v in d.items() if v == value]  
    get_keys(dicxx, '001') # => ['a']
    

正则表达式

表达式全集

  • 十六进制字符串分割

    import re
    subject = '080045'
    result = re.sub(r"(?<=\w)(?=(?:\w\w)+$)", " ", subject)
    # => '08 00 45'
    

CRC校验

  • crcmod

    算法参数

    Name Polynomial Reversed Init-value XOR-out Check
    crc-8 0x107 False 0x00 0x00 0xF4
    crc-8-darc 0x139 True 0x00 0x00 0x15
    crc-8-i-code 0x11D False 0xFD 0x00 0x7E
    crc-8-itu 0x107 False 0x55 0x55 0xA1
    crc-8-maxim 0x131 True 0x00 0x00 0xA1
    crc-8-rohc 0x107 True 0xFF 0x00 0xD0
    crc-8-wcdma 0x19B True 0x00 0x00 0x25
    crc-16 0x18005 True 0x0000 0x0000 0xBB3D

    crcmod.mkCrcFun的参数解析

    • poly –用于计算CRC的生成多项式。该值指定为Python整数或长整数。该整数中的位是多项式的系数。允许的唯一多项式是那些生成8、16、24、32或64位CRC的多项式。
    • rev-当为True时,选择位反转算法的标志。默认为 True,因为位反转算法更有效。
    • initCrc –用于开始CRC计算的初始值。该初始值应为初始移位寄存器值,如果使用反向算法则应反向,然后与最终XOR值进行XOR。这等效于算法应针对零长度字符串返回的CRC结果。默认设置为所有位,因为该起始值将考虑前导零字节。从零开始将忽略所有前导零字节。
    • xorOut –与计算出的CRC值进行XOR的最终值。由某些CRC算法使用。默认为零。
    import binascii # binascii --- 二进制和 ASCII 码互转
    import crcmod
      
    #CRC8
    c8=crcmod.predefined.mkCrcFun('CRC-8')
    hex(c8("Test".encode()))
    #CRC16
    c16=crcmod.predefined.mkCrcFun('CRC-16') #'crc-16'默认为IBM
    crc16=crcmod.mkCrcFun(0x18005,rev=True,initCrc=0x0000,xorOut=0x0000)
    crc16modbus=crcmod.mkCrcFun(0x18005,rev=True,initCrc=0xFFFF,xorOut=0x0000)
    crc16m = crcmod.predefined.mkCrcFun('modbus') 
    print(hex(crc16(b"Test")))
      
    # 自定义CRC算法的功能crcmod.mkCrcFun(...) :CRC16-MODBUS
    def crc16Add(read):
        crc16 =crcmod.mkCrcFun(0x18005,rev=True,initCrc=0xFFFF,xorOut=0x0000)
        data = read.replace(" ","")
        readcrcout=hex(crc16(binascii.unhexlify(data))).upper()
        str_list = list(readcrcout)
        if len(str_list) == 5:
            str_list.insert(2,'0')      # 位数不足补0
        crc_data = "".join(str_list)
        print(crc_data)
        read = read.strip()+' '+crc_data[4:]+' '+crc_data[2:4]
        print('CRC16校验:',crc_data[4:]+' '+crc_data[2:4])
        print('增加Modbus CRC16校验:>>>',read)
        return read
       
    #modbus rtu实现
    def calc_crc(data): #modbus rtu
        crc = 0xFFFF
        for pos in data:
            crc ^= pos 
            for i in range(8):
                if ((crc & 1) != 0):
                    crc >>= 1
                    crc ^= 0xA001
                else:
                    crc >>= 1
        return crc
    a="fc5a"
    data = bytearray.fromhex(a)
    print("crc校验modbus:",hex(calc_crc(data)),"%04X"%(calc_crc(data))) # 0x6d36 6D36
      
    if __name__ == '__main__':
        crc16Add("01 03 08 00 01 00 01 00 01 00 01")
        # CRC16校验: 28 D7
        # 增加Modbus CRC16校验:>>> 01 03 08 00 01 00 01 00 01 00 01 28 D7
    

进制转换

  • [ ] 2进制 8进制 10进制 16进制
      2进制 - bin(int(n,8)) bin(int(n,10)) bin(int(n,16))
      8进制 oct(int(n,2)) - oct(int(n,10)) oct(int(n,16))
      10进制 int(n,2) int(n,8) - int(n,16)
      16进制 hex(int(n,2)) hex(int(n,8)) hex(int(n,10)) -
  • 前缀:2进制是0b,8进制是0o,16进制是0x

    去除:切片操作[2:]

  • format函数:

    # to二进制
    # 先将2进制的数转换为10进制,然后在format的槽中添加一个b,等价于实现了bin函数的功能,此结果是不带有0b前缀的
    print("{:b}".format(int(input(),2)))
    
  • ASCII码和字母之间的转换:

    字母转ASCII:

    ​ ord(c):参数是长度为1的字符串,简称字符。

    ASCII转字母:

    ​ chr(i):返回一个字符,字符的ascii码等于参数中的整形数值。

    特殊ASCII码:

    ​ A-65,Z-90,a-97,z-122,0-48,9-57

补零

  n = "123"
  s = n.zfill(5)
  assert s == "00123"

  n = 123
  s = "%05d" % n
  s = "{:05d}".format(n)
  assert s == "00123"

Json

docs

# -*- coding:utf-8 -*-  
import json
# dict
data = [{ 'a' : 1, 'c' : 2, 'b' : 3, '中文' : 9 } ]

# json.dumps()方法实现python类型转化为json字符串
print(json.dumps(data))
# sort_keys排序 indent缩进 separators分隔 ensure_ascii中文
data_json = json.dumps(data,sort_keys=True,indent=4,separators(',',':'),ensure_ascii=False)
print(data_json)
# json.loads()方法将JSON文本字符串转换为Python对象
print(json.loads(data_json))

# json.dump()和json.load()来编码和解码JSON文件
filename = 'data-json.json'
with open(filename,'w',encoding='utf-8') as file:
    json.dump(data,file,sort_keys=True,indent=4,separators=(',',':'),ensure_ascii=False)
    #file.write(data_json)
with open(filename,'r',encoding='utf-8') as file:
    print(json.load(file))

str() & repr() ->字符串

print(str('now')) # > now
# 调用对象.__str__(),只输出实例内容
print(repr('now')) # > 'now'
# 调用对象的__repr__(),输出实例内容和实例数据类型