美文网首页
Python知识点

Python知识点

作者: 林逸凡_lyf | 来源:发表于2018-08-24 16:43 被阅读0次

    Python是动态语言,变量类型不固定;也是解释语言
    Python的缺点:
    源码不能加密,执行速度慢

    直接在终端运行.py文件:
    在.py文件头部加上 #!/usr/bin/env python3
    在终端执行 chmod a+x hello.py 给文件执行权限
    终端执行 ./hello.py 执行文件

    输入输出

    print("Hello world")
    print(1+1)
    print(a, b) #print多个参数,用空格连接
    print('''line1
    line2
    line3''') #使用''' '''显示多行内容
    print('%2d-%02d' % (3, 1)) # 格式('%d' % a)
    print('%.2f' % 3.1415926) # %d是整形,%f浮点型,%s字符型
    name = input() #输入
    name = input('please enter your name: ') #带提示的输入
    

    基础类型

    3**2 # 3的2次方
    #类型转换
    float('1.9')
    int(1.9)
    right = True #布尔值:True False
    none = None #空值用None表示,类似于nil
    10 / 3 # == 3.33333, 得到一个浮点数
    10 // 3 # == 3, 得到一个整数,类似于通常的整数除法
    

    编码

    ASCII编码是一个字节,只能显示少量字符
    Unicode编码是两个字节,可以显示所有字符,用于显示
    UTF-8是可变长度编码,根据字符决定编码长度,一般用于传输

    # -*- coding: utf-8 -*-  # 文件开头加这个表示使用utf-8编码,可以显示中文
    ord('A') # 65
    ord('中') # 20013, 获取字符十进制编码
    chr(66) # B
    chr(25991) # 文,将编码转换为字符
    x = b'ABC' #b代表bytes类型
    'ABC'.encode('ascii') # 用encode将字符串编码为指定的bytes
    '中文'.encode('utf-8')
    x.decode('ascii') # 用decode将bytes变为string
    

    list和tuple

    list中可以存放不同类型的成员

    # list可变
    classmates = ['A', 'B', 'C'] # 使用[]
    len(classmates) # 使用len()获取长度,同样可对string使用
    classmates[-1] # C, -1表示直接取最后一个元素
    classmates[-2] # B, 取倒数第二个元素,以此类推
    classmates.append('D') # 添加
    classmates.insert(1, 'J') # 插入到位置1
    classmates.pop() # 删除最后一个元素
    classmates.pop(2) # 删除指定index的元素
    classmates.remove('C') # 删除指定元素
    # tuple初始化后不可变
    classmates = ('A', 'B', 'C') # 不可修改
    t = (1,) # 定义一个元素的tuple最后加逗号
    newClassmates = classmates # 这里没有创建新list,newClassmates和classmates共享内存(类似C++指针)
    newClassmates = classmates[:] # 使用切片复制list
    newClassmates = list(classmates) # 使用list()复制list
    

    条件判断

    age = 3
    if age > 18: # 注意冒号
        print('Adult') # 注意缩进
    elif age >= 8: # else if写作elif
        print('Teenager')
    else:
        print('Infancy')
    if age < 100
        pass # 表示什么都不做
    if num in nums: # 元素在list中
    if name not in names: # 元素不在list中
    if a < b and c > d: # 与
    if a < b or c >d: # 或
    

    循环

    names = ['A', 'B', 'C', 'D']
    for name in names: # 使用:
        print(name)
    for x in range(100) : # range(x)生成0到x-1的整数序列
        x += x
    while n >0:
        print('xxx')
    

    字典和集合

    d = {'A': 95, 'B': 100, 'C': 60}
    #判断key是否存在
    'D' in d # False
    d.get('D') # 返回None
    d.pop('key') # 删除
    #set
    s = set([1,2,3,4]) # 使用一个list来初始化
    s.add(5) # 添加元素
    s.remove(3) # 删除元素
    

    函数

    def my_abs(x): # 使用def定义函数,不需要返回类型
        if not isinstance(x, (int, float)): # 使用isinstance进行参数检查
            raise TypeError('bad operand type')
        if x >= 0:
            return x
        else:
            return -x
    def empty():
        pass  # 空函数
    # 返回多个返回值
    def move(x, y, step, angle=0):
        nx = x + step * math.cos(angle)
        ny = y - step * math.sin(angle)
        return nx, ny  # 返回的实际是一个tuple
    # 可变参数
    def calc(*numbers): # 参数前加*
        sum = 0
        for n in numbers: # 实际接受到的是一个tuple
            sum = sum + n * n
        return sum
    calc(1,2,3) # 直接调用
    nums = [1, 2, 3]
    calc(*nums) # 通过list调用
    # 关键字参数
    def person(name, age, **kw): # 使用**表示任意个含参数名的参数
        print('name:', name, 'age:', age, 'other:', kw)
    person('Bob', 35, city='Beijing') # 直接调用
    person('Adam', 45, gender='M', job='Engineer') # name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
    extra = {'city': 'Beijing', 'job': 'Engineer'}
    person('Jack', 24, **extra) # 通过list调用, name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
    def person(name, age, *, city, job): # 只接受city和job关键字的参数
        print(name, age, city, job)
    def person(name, age, *args, city, job): # 如果有可变参数,可以不写*
        print(name, age, city, job)
    # 参数定义顺序
    def f1(a, b, c=0, *args, d, **kw): # 必选参数,默认参数,可变参数,命名关键字参数(d),关键字参数
        print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
    

    递归

    每一层递归会占用一层栈,递归过多会导致栈溢出,使用尾递归可能可以解决此问题(如果编译器作过优化,python编译器没有)

    def fact(n):
        return fact_iter(n, 1)
    def fact_iter(num, product):
        if num == 1:
            return product
        return fact_iter(num - 1, num * product) # 尾递归,返回递归函数本身,不含其他运算
    

    切片

    可用于list, tuple, string

    L = [1,2,3,4,5]
    L[0:3] # [1,2,3] 可以看作 0..<3
    L[:3] # [1,2,3]
    L[1:3] # [2,3]
    L[-2:] # [4,5]
    L[-2:-1] # [4]
    L = list(range(100)) # 从range创建list
    L[:10:2] # [0,2,4,6,8]
    L[::5] # [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
    

    迭代

    isinstance('abc', Iterable) # 判断变量是否可迭代
    # dict迭代
    d = {'a': 1, 'b': 2, 'c': 3}
    for key in d: # 默认迭代key
        pass
    for value in d.values(): # 迭代value
        pass
    for k, v in d.items(): # 同时迭代key和value
        pass
    for i, value in enumerate(['A', 'B', 'C']): # enumerate()函数同时返回index和值
        print(i, value)
    

    列表生成式

    list(range(1, 11)) # [1,2,...9,10]
    [x * x for x in range(1, 11)] # x平方组成的list,[1,4,9,...,81,100]
    [x * x for x in range(1, 11) if x % 2 == 0] # for循环接判断条件,[4,16,36,64,100]
    [m + n for m in 'ABC' for n in 'XYZ'] # 两层循环全排列,[AX,AY,AZ,BX,...CY,CZ]
    

    生成器(generator)

    一边循环一边计算,这样可以只访问前面一定数量的元素。把[ ]改成( )

    L = [x * x for x in range(10)] # 列表生成式
    g = (x * x for x in range(10)) # 生成器、
    next(g) # 打印g的下一个元素
    for n in g: # 使用for循环遍历g
        print(n)
    # 定义生成器
    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b # 使用yield关键字,执行时遇到yield返回,下次执行从yield处开始
            a, b = b, a + b
            n = n + 1
        return 'done'
    

    迭代器(Iterator)

    Iterator和Iterable是两个东西。
    能被for循环迭代的是Iterable,如list,tuple。
    能调用next()的是Iterator,如generator。Iterator是惰性的,初始时可能不知道长度,在需要返回下一个数据时才进行计算。

    isinstance(iter('abc'), Iterator) # 使用iter()将Iterable转化为Iterator 
    # 迭代器循环
    it = iter([1, 2, 3, 4, 5])
    while True:
        try:
            # 获得下一个值:
            x = next(it)
        except StopIteration:
            # 遇到StopIteration就退出循环
            break
    

    函数式编程

    python中可以将函数作为一种类型(类似C++函数指针)

    # 高阶函数
    def add(x, y, f): # 传入参数有函数
        return f(x) + f(y)
    print(add(-5, 6, abs))
    #map函数
    def f(x):
        return x * x
    r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) # 传入一个函数和一个list,让函数作用于每个元素,并返回一个新list
    list(r) # r是Iterator,使用list()转成list
    #reduce,传入一个函数和一个list,reduce把函数计算结果和list后面的元素进行累积计算
    def fn(x, y): # 传入reduce的函数接受两个参数
        return x * 10 + y
    reduce(fn, [1, 3, 5, 7, 9]) # 13579
    #map reduce 版string to int
    DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    def char2num(s):
        return DIGITS[s]
    def str2int(s):
        return reduce(lambda x, y: x * 10 + y, map(char2num, s)) # map将s转换成int list,reduce再将list元素组成一个数字
    

    filter

    接受一个函数和一个list,对每个list元素执行函数,根据返回True或者False将结果放入输出list中

    def is_odd(n):
        return n % 2 == 1
    list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])) # [1, 5, 9, 15]
    

    sorted

    sorted([36, 5, -12, 9, -21], key=abs) # key参数代表排序方法
    sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True) # reverse参数代表反向排序
    students = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
    sorted(students, key=itemgetter(0)) # 根据第一个参数排序
    sorted(students, key=itemgetter(1)) # 根据第二个参数排序
    f = itemgetter(2) # 获取第3个元素
    f(students)  # students[2]
    

    函数高级用法

    # 函数作为返回值
    # 返回函数不要引用任何循环变量,或者后续会发生变化的变量!
    def lazy_sum(*args):
        def sum(): # sum可以使用外部参数,闭包
            ax = 0
            for n in args:
                ax = ax + n
            return ax
        return sum # 返回时,相关参数和变量会保存在sum中
    f = lazy_sum(1, 3, 5, 7, 9) # 此时不计算求和
    f() # 实际进行求和
    # lambda函数
    # lambda x: x*x, 使用lambda关键字,冒号前面是参数,后面是表达式,返回结果为表达式结果
    list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
    # 装饰器
    def log(func): # 定义装饰器
        # 将func的__name__赋值给wrapper
        @functools.wraps(func) 
        def wrapper(*args, **kw): #(*args, **kw)表示可以传入任何参数
            print('call %s():' % func.__name__)
            return func(*args, **kw)
        return wrapper
    @log
    def now(): # 使用装饰器,等价于now = log(now)
        print('2015-3-25')
    # 偏函数
    # 把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数比调用原函数更简单
    int2 = functools.partial(int, base=2) # int2 = int(x, base = 2)
    int2('1000000')
    

    模块

    Python中,一个py文件就称为一个模块
    每个文件夹称为一个包,包中必须有init.py文件

    #!/usr/bin/env python3 # 可以在linux上直接执行
    # -*- coding: utf-8 -*- # 使用utf-8编码
    
    ' a test module '
    
    __author__ = 'Michael Liao' # 文件作者
    
    import sys # 导入模块
    
    def test():
        args = sys.argv
        if len(args)==1:
            print('Hello, world!')
        elif len(args)==2:
            print('Hello, %s!' % args[1])
        else:
            print('Too many arguments!')
    
    def _private_1(name): # 私有变量、函数名以_开头(实际上可访问,只是约定)
        return 'Hello, %s' % name
    
    if __name__=='__main__': # 在命令行运行时会进入这个判断,可用于测试
        test()
    

    面向对象编程

    # 声明一个类
    class Student(object): # 使用class关键字,括号内表示父类,没有父类则继承object类
        count = 0 # 类属性,所有实例都能访问
        def __init__(self, name, score): # 使用__init__定义构造函数,第一个参数为self
            self.name = name # 类内不用声明成员变量,直接使用
            self.__score = score # __开头表示私有成员
        def print_score(self): # 成员函数第一个参数为self
            print('%s: %s' % (self.name, self.score))
    bart = Student('Bart Simpson', 59)
    bart.age = 8 # 在外部给实例添加成员
    

    动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的

    class Animal(object): # 基类
        def run(self):
            print('Animal is running...')
    class Dog(Animal): # 子类
        def run(self):
            print('Dog is running...')
    class Timer(object): # 鸭子类型(不是Animal,但实现了run( ))
        def run(self):
            print('Start...')
    def run_twice(animal):
        animal.run()
        animal.run()
    run_twice(Animal())
    run_twice(Dog())
    run_twice(Timer()) # 只要实现了run(), 便可传入执行
    

    辅助方法

    type(1) # 获取类型
    isinstance(1, int) # 等效于type()
    isinstance(dog, Dog) # 判断class
    dir(dog) # 获得对象的所有属性和方法
    hasattr(dog, 'x') # 判断dog是否有属性x, 对函数同样适用
    getattr(dog, 'x') # 获得属性x,如果没有抛出AttributeError
    getattr(dog, 'z', 404) # 获取属性'z',如果不存在,返回默认值404
    setattr(dog, 'y', 19) # 设置一个属性'y',如果有就修改,没有就新建
    

    高级面向对象

    # 动态给类添加函数
    def set_score(self, score):
        self.score = score
    Student.set_score = set_score
    from types import MethodType # 给类添加
    s.set_age = MethodType(set_age, s) # 给实例添加
    # __slots__
    class Student(object):
        __slots__ = ('name', 'age') # 限制类只能添加name和age属性(仅对本身起效,子类不影响)
    # @property # 将方法变成属性
    class Student(object):
        @property # getter
        def birth(self):
            return self._birth
        @birth.setter # setter
        def birth(self, value):
            self._birth = value
        @property # 只读属性
        def age(self):
            return 2015 - self._birth
    s = Student()
    s.birth = 2010
    age = s.age
    # 多重继承
    class Bat(Mammal, Flyable): # 括号中写所有父类
        pass
    

    定制类

    # __str__() 用于print
    class Student(object):
        def __init__(self, name):
            self.name = name
        def __str__(self):
            return 'Student object (name: %s)' % self.name
        __repr__ = __str__ # __repr__用于直接显示,一般设为等于__str__
        def __call__(self): # 直接调用实例
            print('My name is %s.' % self.name)
    print(Student('Michael')) # 此时调用__str__
    s = Student()
    s # 此时调用__repr__
    s() # 此时调用__call__
    # __iter__, 用于允许遍历
    class Fib(object):
        def __init__(self):
            self.a, self.b = 0, 1 # 初始化两个计数器a,b
        def __iter__(self):
            return self # 实例本身就是迭代对象,故返回自己
        def __next__(self):
            self.a, self.b = self.b, self.a + self.b # 计算下一个值
            if self.a > 100000: # 退出循环的条件
                raise StopIteration()
            return self.a # 返回下一个值
        def __getitem__(self, n):
            if isinstance(n, int): # n是索引
                a, b = 1, 1
                for x in range(n):
                    a, b = b, a + b
                return a
            if isinstance(n, slice): # n是切片
                start = n.start
                stop = n.stop
                if start is None:
                    start = 0
                a, b = 1, 1
                L = []
                for x in range(stop):
                    if x >= start:
                        L.append(a)
                    a, b = b, a + b
                return L
    for n in Fib(): # 不断调用__next__
        print(n)
    Fib()[10] # 此时调用__getitem__
    Fib[:10] # 调用切片
    

    枚举

    from enum import Enum, unique
    Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')) # name + members
    for name, member in Month.__members__.items(): # __members__获取成员
        print(name, '=>', member, ',', member.value)
    
    @unique # @unique关键字检查每个元素的唯一性
    class Weekday(Enum):
        Sun = 0 # Sun的value被设定为0
        Mon = 1
        Tue = 2
        Wed = 3
        Thu = 4
        Fri = 5
        Sat = 6
    

    错误处理

    错误是class

    try: # 使用try来捕获函数
        print('try...')
        r = 10 / 0
        print('result:', r)
    except ValueError as e: # 如果抛出ValueError执行以下代码
        print('ValueError:', e)
    except ZeroDivisionError as e:
        print('except:', e)
    finally: # 最后执行以下代码(不管抛不抛出错误都会执行)
        print('finally...')
    with open('/path/to/file', 'r') as f: # 等效于try
        print(f.read())
    

    使用assert或logging

    $ python -O err.py # 命令行启动时-o关闭assert
    
    assert n != 0, 'n is zero!' # 如果 n==0,抛出错误
    s = '0'
    n = int(s)
    logging.info('n = %d' % n) # logging不抛出错误,而是存在文件里
    

    IO操作

    f = open('/Users/michael/test.txt', 'r') # r表示读,如果失败,抛出IOError
    f.read() # 读取文件的全部内容
    f.read(size) # 读取一定size的内容
    f.readline() # 读取一行内容
    f.readlines() # 按行读取内容,返回list
    f.close() # 关闭文件
    f = open('/Users/michael/test.jpg', 'rb') # rb表示读取二进制文件
    f.read()
    f = open('/Users/michael/test.txt', 'w') # w代表写文件
    f.write('Hello, world!')
    f.close()
    

    StringIO 在内存中读写str
    BytesIO 在内存中读写二进制文件
    操作文件夹

    os.path.abspath('.') # 查看绝对目录
    os.path.join('/Users/michael', 'testdir') # 拼接目录
    os.mkdir('/Users/michael/testdir') # 创建一个目录
    os.rmdir('/Users/michael/testdir') # 删掉一个目录
    

    pickling,持久化存储

    d = dict(name='Bob', age=20, score=88)
    f = open('dump.txt', 'wb')
    pickle.dump(d, f) # 将d写入f
    c = pickle.load(f) # 从f中读入数据
    f.close()
    #json
    json.dumps(d) # 将d储存为json格式
    json_str = '{"age": 20, "score": 88, "name": "Bob"}'
    json.loads(json_str) # 读取json内容
    def student2dict(std):
        return {
            'name': std.name,
            'age': std.age,
            'score': std.score
        }
    print(json.dumps(s, default=student2dict)) # 传入自定义方法序列化class
    print(json.dumps(s, default=lambda obj: obj.__dict__)) # __dict__将对象转化为dict
    

    常用内建模块

    datetime

    from datetime import datetime # 有datetime模块和datetime类
    now = datetime.now() # 获取当前时间
    dt = datetime(2015, 4, 19, 12, 20) # 创建指定时间
    dt.timestamp() # 将datetime转换为timestamp,1429417200.0
    toDt = datetime.fromtimestamp(t) # 将timestamp转换为datetime(本地时间)
    cday = datetime.strptime('2015-6-1 18:19:59', '%Y-%m-%d %H:%M:%S') # str转换为datetime
    cday.strftime('%a, %b %d %H:%M') # datetime转换为str
    

    collections

    # namedtuple
    from collections import namedtuple
    Point = namedtuple('Point', ['x', 'y']) # 命名的tuple
    p = Point(1, 2) # 像类一样使用
    p.x
    # deque 双向链表
    q = deque(['a', 'b', 'c'])
    q.appendleft('y') # 插入头部
    q.popleft() # 删除头部
    # OrderedDict 按照key插入的顺序排序
    od = OrderedDict([('b', 2), ('c', 3), ('a', 1)]) # od = [b..,c..,a..]
    

    装饰器

    装饰器的本质是赋值

    def use_logging(func):
    
    def wrapper():
        logging.warn("%s is running" % func.__name__)
        return func()   # 把 foo 当做参数传递进来时,执行func()就相当于执行foo()
    return wrapper
    
    def foo():
        print('i am foo')
    
    foo = use_logging(foo)  # 因为装饰器 use_logging(foo) 返回的时函数对象 wrapper,这条语句相当于  foo = wrapper
    foo()
    
    @use_logging # 等价于foo = use_logging(foo)
    def foo1():
        print("i am foo1")
    
    foo1()
    
    class Foo3(object):
        def __init__(self, func):
            self._func = func
    
        def __call__(self):
            print ('class decorator runing')
            self._func()
            print ('class decorator ending')
    
    @Foo3 #类装饰器
    def bar():
        print ('bar')
    
    bar() #调用__call__

    相关文章

      网友评论

          本文标题:Python知识点

          本文链接:https://www.haomeiwen.com/subject/rrbbiftx.html