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.
网友评论