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

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 "", line 1, in 
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 
    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 
    print(10 / n)
ZeroDivisionError: division by zero

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

// 启动
$ python -m pdb err.py
> /Users/michael/Github/learn-python3/samples/debug/err.py(2)()
-> 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)()
-> n = int(s)
(Pdb) n
> /Users/michael/Github/learn-python3/samples/debug/err.py(4)()
-> 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)()
-> print(10 / n)
(Pdb) p n
0
(Pdb) c
Traceback (most recent call last):
  File "err.py", line 7, in 
    print(10 / n)
ZeroDivisionError: division by zero

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

你可能感兴趣的:(python 的常用内置函数 && 错误)