美文网首页
python 的常用内置函数 && 错误

python 的常用内置函数 && 错误

作者: 风___________ | 来源:发表于2021-04-23 13:49 被阅读0次

    0. python的数据类型 和 关键字

    可变类型:list dict
    
    
    不可变类型:int str float bool
    
    关键字:
    assert n != 0, 'n is zero!' # 断言
    

    1. 常用函数

    print() # 输出到控制台
    len() # 获取长度,调用的其实是 __len__()方法,自定义对象想支持len()就实现__len__()
    isinstance() # 是否是某个类型 eg:isinstance(' ',str)  isinstance(' ',(str,int))   // dict, str,int, tuple, dict, Iterable, Iterator等等等
    a = input() # 从控制台输入
    list.pop(0)  #   list删除第一个元素 
    list.append('admin')  #  list追加
    list.insert(1,'aaa')  #   list插入
    set.add(5) #  set添加
    set.remove(5) #  set删除 set = {1,2,2,2,4}
    dict.get("3",3)  # dict获取key对应的value,并给个默认值
    dir()  # 打印对象的所有方法属性
    map(lambda x:x**2,[1,2,3]) # 数组每个对象执行lambda x:x**2并把结果输出,第一个参数对应的函数返回值随意
    filter(lambda x: x < 0, number_list) # 数组过滤,第一个参数对应的函数返回值是true false
    reduce( lambda x, y: x * y, [1, 2, 3, 4] ) # 对一个列表进行一些计算并返回结果,第一个参数对应的函数两个参数
    range(5) # 生成整数序列[0,1,2,3,4]
    int() str() bool() max() list()# 类型转化和最大值
    type()  #可以查看一个类型或变量的类型eg:type(123)==int 
    type() #既可以返回一个对象的类型,又可以创建出新的类型 eg:创建Hello class ---  def fn(self, name='world'):  Hello = type('Hello', (object,), dict(hello=fn)) 第一个class的名称,第二个参数继承的父类集合(多重继承),第三个参数是class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上
    types.FunctionType  types.BuiltinFunctionType  types.LambdaType types.GeneratorType # types 模块中类型常量 类似的有:dict, str,int, tuple, dict, Iterable, Iterator等
    getattr(obj, 'y') # 获取实例obj的y属性值
    setattr(obj, 'y', 19) # 设置实例obj的y属性值
    hasattr(obj, 'y')  #  实例obj是否有名为y的属性值
    del s.name # 删除实例的name属性
    iter() # Iterable(可迭代)对象生成Iterator(迭代器)对象
    hex(n2) # hex()函数把一个整数转换成十六进制
    def set_age(self,age): self.age = age  ; s.set_age = MethodType(set_age,s) # 给实例绑定一个set_age方法 
    Student.set_age = MethodType(set_age, Student) # 给Student绑定了方法
    callable() # 判断一个对象是否是“可调用”对象。对象如果能被调用需要实现def __call__(self):函数
    Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')) # from enum import Enum  定义一个枚举
    setUp() # 单元测试中在每调用一个测试方法之前执行
    tearDown() # 单元测试中在每调用一个测试方法之后执行
    with open('/path/to/file', 'r') as f: # 读取文件,f是file-like Object(file-like Object不要求从特定类继承,只要写个read()方法就行)
    f.readlines() # 一次读取所有内容并按行返回list
    f.read() # 一次性读取文件的全部内容
    f.readline() # 读取一行内容
    with open('/Users/michael/test.txt', 'w') as f: #  写文件打开文件的方式
    f.write('xxx') # 写入文件并覆盖
    import json # 倒入json模块
    json.dumps(d,default=函数) # default = 转换函数 参数是对象返回值是dic,作用是实例转dic转json,ensure_ascii=True -非ASCII字符自动转义
    json.loads(json_str, object_hook=反序列化函数) # object_hook = 反序列化函数 参数是dic 返回值是对象实例,作用是jsonsrting转为dic转为对象
    
    
    

    2. PYTHON 常见的错误类型

    // 代码缩近不对
    IndentationError:unindent does not match any outer indentation level
    
    // 找不到模块:
    >>> import mymodule
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ImportError: No module named mymodule
    
    // 解决:默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中:
    >>> import sys
    >>> sys.path
    ['', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6', ..., '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages']
    
    // 如果我们要添加自己的搜索目录,有两种方法:
    # 1. 直接修改sys.path,添加要搜索的目录(运行时修改,运行结束后失效)
    >>> import sys
    >>> sys.path.append('/Users/michael/my_py_scripts')
    # 2. 设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响。
    
    

    3. 特殊变量 && 函数 :看到类似slots这种形如xxx的变量或者函数名就要注意,这些在Python中是有特殊用途的。

    1. 
    __slots__: 其定义的属性仅对当前类实例起作用,对继承的子类是不起作用(除非在子类中也定义__slots__,这样,子类实例允许定义的属性✨✨✨
    就是自身的__slots__ + 父类的__slots__。)
    class Student(object):
        __slots__ = ('name', 'age') # 限制class实例能添加的属性
    
    @ property + @xxx.setter:Python内置的装饰器,负责把一个方法变成属性调用的xxx是添加的属性名
    2. 
    def __str__(self): # print(实例变量)的时候会打印此函数的返回值
    3. 
    def __repr__(): # 调试服务直接打印对象会打印此函数的返回值 也可以偷懒。  __repr__ = __str__(python 一切都是对象,这个意思是__repr__变量指向了__str__变量指向的函数)
    4.
    def __iter__(self): # 如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象
    def __next__(self): # 迭代对象被迭代时,会不断调用__next__函数,知道遇到StopIteration错误时退出循环。
    eg:
    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 # 返回下一个值
    5. 
      def __getitem__(self, n): # 像list那样按照下标取出元素,需要实现__getitem__()方法
    # list支持切片语法,因为切片语法时传入的n是个切片对象slice
    eg:(支持简单切片语法的自定义对象)
    class Fib(object):
        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
    6. 
      def __setitem__(self, n,v): # 赋值
      def __delitem__(self, n,v): # 删除
    
    7.
      def __getattr__(self, attr): # 当调用不存在的属性和方法时,Python解释器会调用__getattr__,只有在没有找到属性和方法的情况下,才调用__getattr__,已有的属性和方法,不会在__getattr__中查找
    eg:
    # 意思是如果没定义age,但是尝试获取的时候就返回25,尝试获取其余没定义的属性就报错
    class Student(object):
    
        def __getattr__(self, attr):
            if attr=='age':
                return lambda: 25
            raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)
    8. 
        def __call__(self): # 对实例进行直接调用,会调用此方法。
    eg:
    class Student(object):
        def __init__(self, name):
            self.name = name
    
        def __call__(self):
            print('My name is %s.' % self.name)
    >>> s = Student('Michael')
    >>> s() # self参数不要传入
    My name is Michael. # 调用了 __call__ 方法,一个实例也可以看为一个“函数” __call__就是实例的函数体
    
    

    4.异常处理

    try:
        print('try...')
        r = 10 / int('2')
        print('result:', r)
    except ValueError as e:
        print('ValueError:', e)
    except ZeroDivisionError as e:
        print('ZeroDivisionError:', e)
    else:
        print('no error!')
    finally:
        print('finally...')
    print('END')
    # Python的错误其实也是class,所有的错误类型都继承自BaseException,所以在使用except时需要注意的是,它不但捕获该类型的错误
    # ,还把其子类也“一网打尽”。比如:
    try:
        foo()
    except ValueError as e:
        print('ValueError')
    except UnicodeError as e:
        print('UnicodeError')
    第二个except永远也捕获不到UnicodeError,因为UnicodeError是ValueError的子类,如果有,也被第一个except给捕获了。
    不需要在每个可能出错的地方去捕获错误,只要在合适的层次去捕获错误就可以了,如果错误没有被捕获,它就会一直往上抛,最后被Python解释器捕获,打印一个错误信息,然后程序退出。来看看err.py:
    # err.py:
    def foo(s):
        return 10 / int(s)
    
    def bar(s):
        return foo(s) * 2
    
    def main():
        bar('0')
    main()
    
    #执行,结果如下:
    Traceback (most recent call last):
      File "err.py", line 11, in <module>
        main()
      File "err.py", line 9, in main
        bar('0')
      File "err.py", line 6, in bar
        return foo(s) * 2
      File "err.py", line 3, in foo
        return 10 / int(s)
    ZeroDivisionError: division by zero
    
    # 常见错误处理方式
    # err_reraise.py
    
    def foo(s):
        n = int(s)
        if n==0:
            raise ValueError('invalid value: %s' % s)
        return 10 / n
    
    def bar():
        try:
            foo('0')
        except ValueError as e:
            print('ValueError!')
            raise
    
    bar()
    由于当前函数不知道应该怎么处理该错误,所以,最恰当的方式是继续往上抛,让顶层调用者去处理。
    
    

    断言

    def foo(s):
        n = int(s)
        assert n != 0, 'n is zero!'
        return 10 / n
    
    def main():
        foo('0')
    
    // Python解释器时可以用-O参数来关闭assert:
    $ python -O err.py # 断言的开关“-O”是英文大写字母O,不是数字0。关闭后,你可以把所有的assert语句当成pass来看。
    

    logging:把print()替换为logging是第3种调试程序错误信息方式

    import logging
    logging.basicConfig(level=logging.INFO)
    
    s = '0'
    n = int(s)
    logging.info('n = %d' % n)
    print(10 / n)
    // 输出
    $ python err.py
    INFO:root:n = 0
    Traceback (most recent call last):
      File "err.py", line 8, in <module>
        print(10 / n)
    ZeroDivisionError: division by zero
    

    pdb :调试器pdb,让程序以单步方式运行,可以随时查看运行状态

    // 启动
    $ python -m pdb err.py
    > /Users/michael/Github/learn-python3/samples/debug/err.py(2)<module>()
    -> s = '0'
    // 以参数-m pdb启动后,pdb定位到下一步要执行的代码-> s = '0'。输入命令l来查看代码:
    (Pdb) l
      1     # err.py
      2  -> s = '0'
      3     n = int(s)
      4     print(10 / n)
    // 输入命令n可以单步执行代码:
    (Pdb) n
    > /Users/michael/Github/learn-python3/samples/debug/err.py(3)<module>()
    -> n = int(s)
    (Pdb) n
    > /Users/michael/Github/learn-python3/samples/debug/err.py(4)<module>()
    -> print(10 / n)
    // 任何时候都可以输入命令p 变量名来查看变量:
    (Pdb) p s
    '0'
    (Pdb) p n
    0
    // 输入命令q结束调试,退出程序:
    (Pdb) q
    
    

    pdb.set_trace() :调试常用

    // 这个方法也是用pdb,但是不需要单步执行,我们只需要import pdb,然后,在可能出错的地方放一个pdb.set_trace(),就可以设置一个断点:
    # err.py
    import pdb
    
    s = '0'
    n = int(s)
    pdb.set_trace() # 运行到这里会自动暂停
    print(10 / n)
    // 运行代码,程序会自动在pdb.set_trace()暂停并进入pdb调试环境,可以用命令p查看变量,或者用命令c继续运行:
    $ python err.py 
    > /Users/michael/Github/learn-python3/samples/debug/err.py(7)<module>()
    -> print(10 / n)
    (Pdb) p n
    0
    (Pdb) c
    Traceback (most recent call last):
      File "err.py", line 7, in <module>
        print(10 / n)
    ZeroDivisionError: division by zero
    

    IDE
    如果要比较爽地设置断点、单步执行,就需要一个支持调试功能的IDE.

    相关文章

      网友评论

          本文标题:python 的常用内置函数 && 错误

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