赞
踩
python 默认变量都是字符串
C:\Users\Jarvis\AppData\Roaming\pip -> pip.ini
Jarvis是用户名
阿里云数据源不如清华源
[global]
timeout = 10000
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
临时使用:
可以在使用pip的时候在后面加上-i参数,指定pip源
pip install scrapy -i
https://pypi.tuna.tsinghua.edu.cn/simple
Python的主要数值类型是int
和float
。int
可以存储任意大的数:
In [48]: ival = 17239871
In [49]: ival ** 6
Out[49]: 26254519291092456596965462913230729701102721
浮点数使用Python的float
类型。每个数都是双精度(64位)的值。也可以用科学计数法表示:
In [50]: fval = 7.243
In [51]: fval2 = 6.78e-5
不能得到整数的除法会得到浮点数:
In [52]: 3 / 2
Out[52]: 1.5
要获得C-风格的整除(去掉小数部分),可以使用底除运算符//:
In [53]: 3 // 2
Out[53]: 1
迭代一个序列时,你可能想跟踪当前项的序号。手动的方法可能是下面这样:
i = 0
for value in collection:
# do something with value
i += 1
因为这么做很常见,Python内建了一个enumerate
函数,可以返回(i, value)
元组序列:
for i, value in enumerate(collection):
# do something with value
当你索引数据时,使用enumerate
的一个好方法是计算序列(唯一的)dict
映射到位置的值:
In [83]: some_list = ['foo', 'bar', 'baz']
In [84]: mapping = {}
In [85]: for i, v in enumerate(some_list):
....: mapping[v] = i
In [86]: mapping
Out[86]: {'bar': 1, 'baz': 2, 'foo': 0}
sorted
函数可以从任意序列的元素返回一个新的排好序的列表:
In [87]: sorted([7, 1, 2, 6, 0, 3, 2])
Out[87]: [0, 1, 2, 2, 3, 6, 7]
In [88]: sorted('horse race')
Out[88]: [' ', 'a', 'c', 'e', 'e', 'h', 'o', 'r', 'r', 's']
sorted
函数可以接受和sort
相同的参数。
zip
可以将多个列表、元组或其它序列成对组合成一个元组列表:
In [89]: seq1 = ['foo', 'bar', 'baz']
In [90]: seq2 = ['one', 'two', 'three']
In [91]: zipped = zip(seq1, seq2)
In [92]: list(zipped)
Out[92]: [('foo', 'one'), ('bar', 'two'), ('baz', 'three')]
zip
可以处理任意多的序列,元素的个数取决于最短的序列:
In [93]: seq3 = [False, True]
In [94]: list(zip(seq1, seq2, seq3))
Out[94]: [('foo', 'one', False), ('bar', 'two', True)]
zip
的常见用法之一是同时迭代多个序列,可能结合enumerate
使用:
In [95]: for i, (a, b) in enumerate(zip(seq1, seq2)):
....: print('{0}: {1}, {2}'.format(i, a, b))
....:
0: foo, one
1: bar, two
2: baz, three
给出一个“被压缩的”序列,zip
可以被用来解压序列。也可以当作把行的列表转换为列的列表。这个方法看起来有点神奇:
In [96]: pitchers = [('Nolan', 'Ryan'), ('Roger', 'Clemens'),
....: ('Schilling', 'Curt')]
In [97]: first_names, last_names = zip(*pitchers)
In [98]: first_names
Out[98]: ('Nolan', 'Roger', 'Schilling')
In [99]: last_names
Out[99]: ('Ryan', 'Clemens', 'Curt')
reversed
可以从后向前迭代一个序列:
In [100]: list(reversed(range(10)))
Out[100]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
要记住reversed
是一个生成器(后面详细介绍),只有实体化(即列表或for循环)之后才能创建翻转的序列。
【参考:python技巧2:用input同时输入多个数_graysu的博客-CSDN博客】
a,b =input('输入a,b空格隔开:').split()
#此时a,b为str型
a,b =map(int,input('输入a,b空格隔开:').split())
#此时a,b为int型
【参考:textwrap — Text wrapping and filling — Python 3.11.0 documentation】
import textwrap # \ 是格式化换行 # 缩进要一致 str1 = """\ name:{}, sex:{}, age:{}, """.format('Jack', 18,'man' ) print(textwrap.dedent(str1)) # 删除文本中每一行中任何常见的前导空格。 """ name:Jack, sex:18, age:man, """
错误例子
"""\
name:{},
sex:{},
age:{}
"""
"""\
name:{},
sex:{},
age:{}
"""
In [74]: template = '{0:.2f} {1:s} are worth US${2:d}'
在这个字符串中,
{0:.2f}
表示格式化第一个参数为带有两位小数的浮点数。{1:s}
表示格式化第二个参数为字符串。{2:d}
表示格式化第三个参数为一个整数。要替换参数为这些格式化的参数,我们传递format
方法一个序列:
In [75]: template.format(4.5560, 'Argentine Pesos', 1)
Out[75]: '4.56 Argentine Pesos are worth US$1'
【参考:Python输出函数print总结(python print())_THEAQING-CSDN博客】
print(*objects, sep=' ', end='\n', file=sys.stdout)
参数的具体含义如下:
objects --表示输出的对象。输出多个对象时,需要用 , (逗号)分隔。
sep -- 用来间隔多个对象。
end -- 用来设定以什么结尾。默认值是换行符 \n,我们可以换成其他字符。
file -- 要写入的文件对象。
【参考:python - 输入输出 之 字符串前缀u、r、b、f含义_开码河粉-CSDN博客】
r
:转义无效符
在字符串前加r使当前字符串的转义字符无效,按原样输出
print(u"江西") # 江西 print(r'\n hello \v') # \n hello \v # 字符串变量 s='\n hello \v' print(repr(s))# \n hello \v s=r"123\n123\n" print(s) print(type(s)) print(repr(s)) print(type(repr(s))) ''' 123\n123\n <class 'str'> '123\\n123\\n' <class 'str'> ''' # Python3.6新加特性 account='myaijarvis' month=12 print(f'我的微信公众号是:{account},已经连续发文{int(month) * 5}天啦!') # 我的微信公众号是:myaijarvis,已经连续发文60天啦!
【参考:Python repr函数_全村的希望的博客-CSDN博客】
python 数值类型只有 int(整形)、float(浮点型,3.x提供17位有效小数,相当于C语言的double)、complex(复数型)
r = (85-72) / 72 *100
print(r)
print('%.1f%%'%r) # %% -> %
print(f'{r:.1f}%') # f'{变量:格式说明符}'
print('{0:.1f}%'.format(r))
print(1/3)
18.055555555555554
18.1%
18.1%
18.1%
0.3333333333333333
list是一种有序的集合
arr=[]
arr.append(1)
arr.append(2)
arr.append(3)
arr.append(4)
for i in range(0,len(arr)):
print(arr[i],end=' ')# 1 2 3 4
print()
arr.pop() # 删除4
arr.pop(1) # 删除下标为1的数,即数字2
arr.insert(0, 5) # 在下标为0的位置插入5
for a in arr:
print(a,end=' ')# 5 1 3
tuple和list非常类似,但是tuple一旦初始化就不能修改
t=() # 空元组
t=(1,) # 一个元素的元组
【参考:使用dict和set - 廖雪峰的官方网站】
dict的key必须是不可变对象
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} print(d['Michael']) # 95 print(d.get('Bob')) # 75 print(d.get('Jack')) # None print(d.get('Jack',-1)) # 设置默认值-1 d.setdefault('Tom',100) # 添加元素 d.pop('Tracy') # 删除元素 for k,v in d.items(): print(k,v) for i in d: print("%s:%s"%(i,d[i])) ''' Michael 95 Bob 75 Tom 100 '''
请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。
和list比较,dict有以下几个特点:
而list相反:
s = {'Michael' ,'Bob','Tracy'} s.add('Jack') # 添加 s.remove('Tracy') # 删除 for k in s: print(k) ''' Michael Jack Bob ''' s_null=set() # 空集合 print(len(s_null)) # 0
False True
int 0 非0
float 0.0 非0.0
str '' 空字符串 非空字符串
列表 [] 空列表
元组 ()
字典 {}
Python内建的datetime
模块提供了datetime
、date
和time
类型。datetime
类型结合了date
和time
,是最常使用的:
In [102]: from datetime import datetime, date, time
In [103]: dt = datetime(2011, 10, 29, 20, 30, 21)
In [104]: dt.day
Out[104]: 29
In [105]: dt.minute
Out[105]: 30
根据datetime
实例,你可以用date
和time
提取出各自的对象:
In [106]: dt.date()
Out[106]: datetime.date(2011, 10, 29)
In [107]: dt.time()
Out[107]: datetime.time(20, 30, 21)
strftime
方法可以将datetime格式化为字符串:
In [108]: dt.strftime('%m/%d/%Y %H:%M')
Out[108]: '10/29/2011 20:30'
strptime
可以将字符串转换成datetime
对象:
In [109]: datetime.strptime('20091031', '%Y%m%d')
Out[109]: datetime.datetime(2009, 10, 31, 0, 0)
表2-5列出了所有的格式化命令。
当你聚类或对时间序列进行分组,替换datetimes的time字段有时会很有用。例如,用0替换分和秒:
In [110]: dt.replace(minute=0, second=0)
Out[110]: datetime.datetime(2011, 10, 29, 20, 0)
因为datetime.datetime
是不可变类型,上面的方法会产生新的对象。
两个datetime对象的差会产生一个datetime.timedelta
类型:
In [111]: dt2 = datetime(2011, 11, 15, 22, 30)
In [112]: delta = dt2 - dt
In [113]: delta
Out[113]: datetime.timedelta(17, 7179)
In [114]: type(delta)
Out[114]: datetime.timedelta
结果timedelta(17, 7179)
指明了timedelta
将17天、7179秒的编码方式。
将timedelta
添加到datetime
,会产生一个新的偏移datetime
:
In [115]: dt
Out[115]: datetime.datetime(2011, 10, 29, 20, 30, 21)
In [116]: dt + delta
Out[116]: datetime.datetime(2011, 11, 15, 22, 30)
Python中符合序列的有序序列都支持切片(slice),例如列表,字符串,元组。
格式:[start:end:step]
start:起始索引,从0开始,-1表示结束
end:结束索引
step:步长,end-start,步长为正时,从左向右取值。步长为负时,反向取值
注意切片的结果不包含结束索引,即不包含最后的一位,-1代表列表的最后一个位置索引
【参考:切片 - 廖雪峰的官方网站】
L = list(range(100)) print(L) # 1,2,3,....,99 print(L[-1]) # 99 倒数第一个元素的索引是-1 print(L[:5]) # [0, 1, 2, 3, 4] 前5个 print(L[-5:]) # [95, 96, 97, 98, 99] 后5个 # 只写[:]就可以原样复制一个list L2=L[:] # 深复制 print(L2) # tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple: t=(0, 1, 2, 3, 4, 5) print(t[:3]) # (0, 1, 2) # 字符串'xxx'也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串 s='ABCDEFG' print(s[:3]) # 'ABC'
[i:j:k]
其中k<0
=> [n+i:n+j:k]
默认[-1:-n-1:k]
比如[0:n:1] 中间的为0+n=n
; [-1:-n-1:k] 中间的为 -1 + -n = -n-1
最右边编号为-1,索引范围为-n到-1
,-n即第一个
a='123456'
print(a[::-1])
# 默认 print(a[-1:-len(a)-1:-1]) # 默认 -len(a)-1=-7 相当于字符1的前面一个 -6指向字符1
print(a[0::-1])
print(a[1::-1])
print(a[2::-1]) # 从下标为2的元素翻转读取
654321
654321
1
21
321
下面好像有点错误 以后再说
s='Hello World!'
s[-1:-5:-1] # !dlr
a=[1,2,3,4,5,6] b1=a[:] #省略全部,代表截取全部内容,可以用来将一个列表拷给另一个列表(深拷贝) print(b1) 结果:[1, 2, 3, 4, 5, 6] b=a[0:-1:1] #从位置0开始到结束,每次增加1,截取。不包含结束索引位置,-1代表最后一个位置 print(b) 结果:[1, 2, 3, 4, 5] ================== [:end] c1=a[:3] #省略起始位置的索引,以及步长。默认起始位置从头开始,默认步长为1,结束位置索引为3 print(c1) 结果:[1, 2, 3] ================== c=a[0:5:3] #从第一个位置到第6个位置,每3个取一个值 print(c) 结果:[1, 4] d=a[5:0:-1] #反向取值 print(d) 结果:[6, 5, 4, 3, 2] d1=a[::-1] print(d1) 结果:[6, 5, 4, 3, 2, 1]
【参考:迭代 - 廖雪峰的官方网站】
如何判断一个对象是可迭代对象呢?方法是通过collections.abc模块的Iterable类型判断:
from collections.abc import Iterable
print(isinstance('abc', Iterable)) # str是否可迭代
# True
print(isinstance([1, 2, 3], Iterable)) # list是否可迭代
# True
print(isinstance(123, Iterable)) # 整数是否可迭代
# False
对list实现类似Java那样的下标循环怎么办?Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:
for i, value in enumerate(['A', 'B', 'C']):
print(i, value)
0 A
1 B
2 C
for x, y in [(1, 1), (2, 4), (3, 9)]:
print(x, y)
1 1
2 4
3 9
【参考:列表生成式 - 廖雪峰的官方网站】
[x * x for x in range(1, 11)]
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[x * x for x in range(1, 11) if x % 2 == 0]
# [4, 16, 36, 64, 100]
# 全排列
[m + n for m in 'ABC' for n in 'XYZ']
# ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
import os # 导入os模块,模块的概念后面讲到
[d for d in os.listdir('.')] # os.listdir可以列出文件和目录
if … else
在一个列表生成式中,for前面的if … else是表达式,而for后面的if是过滤条件,不能带else
[x for x in range(1, 11) if x % 2 == 0]
# [2, 4, 6, 8, 10]
[x if x % 2 == 0 else -x for x in range(1, 11)]
# [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
【参考:生成器 - 廖雪峰的官方网站】
一边循环一边计算的机制,称为生成器:generator
其创建方式为,把列表推导式两端的方括号改成圆括号:
g = (x * x for x in range(10)) # 注意,这里是圆括号
print(g) # <generator object <genexpr> at 0x000001E584F361B0> generator也是可迭代对象
print(next(g)) # 每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素
for n in g:
print(n)
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done'
'''
t = (b, a + b) # t是一个tuple
a = t[0]
b = t[1]
'''
如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator函数,调用一个generator函数将返回一个generator:
调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator
def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return 'done' f = fib(6) f # <generator object fib at 0x104feaaa0> for n in fib(6): print(n) 1 1 2 3 5 8
https://www.cnblogs.com/ellisonzhang/p/10273843.html
简要理解:yield就是 return 返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后开始。
【参考:迭代器 - 廖雪峰的官方网站】
我们已经知道,可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以使用isinstance()判断一个对象是否是Iterable
对象:
>>> from collections.abc import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
可以使用isinstance()判断一个对象是否是Iterator
对象:
>>> from collections.abc import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()
函数:
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
【参考:高阶函数 - 廖雪峰的官方网站】
让函数的参数能够接收别的函数
def add(x, y, f):
return f(x) + f(y)
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回
>>> def f(x):
... return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
reduce把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
常常与map一起使用
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
# 求和
>>> from functools import reduce
>>> def add(x, y):
... return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25
Python内建的filter()函数用于过滤序列。
和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
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([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]
>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
>>> sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
['about', 'bob', 'Credit', 'Zoo']
# 分别按名字排序: L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)] def by_name(t): return t[0].lower() L2 = sorted(L, key=by_name) print(L2) # 用成绩来进行排序,成绩由高到低 L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)] def by_score(t): return t[1] # return -t[1] 下面就不用 reverse L2 = sorted(L, key=by_score,reverse=True) print(L2)
【参考:返回函数 - 廖雪峰的官方网站】
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
def count(): fs = [] for i in range(1, 4): def f(): return i * i fs.append(f) return fs # 返回一个列表,里面三个数 f1, f2, f3 = count() # 列表自动会给三个变量赋值 # 此时就已经运行count()函数了,然后i=3了 print(f1()) # 9 print(f2()) # 9 print(f3()) # 9
如果一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变:
def count(): def f(j): def g(): return j*j return g fs = [] for i in range(1, 4): fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f() return fs 再看看结果: >>> f1, f2, f3 = count() >>> f1() 1 >>> f2() 4 >>> f3() 9
>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
通过对比可以看出,匿名函数lambda x: x * x实际上就是:
def f(x):
return x * x
匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。
匿名函数也是一个函数对象,利用lambda作为返回值时,得到的是一个函数,而不是一个值。
【参考:装饰器 - 廖雪峰的官方网站】
decorator被称为装饰模式
还不是很理解
【参考:偏函数 - 廖雪峰的官方网站】
【参考:安装第三方模块 - 廖雪峰的官方网站】
模块搜索路径
当我们试图加载一个模块时,Python会在指定的路径下搜索对应的.py文件,如果找不到,就会报错:
>>> 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
['c:\\Users\\Jarvis\\Desktop\\Code\\py',
'C:\\anaconda3\\python37.zip',
'C:\\anaconda3\\DLLs',
'C:\\anaconda3\\lib',
'C:\\anaconda3',
'C:\\Users\\Jarvis\\AppData\\Roaming\\Python\\Python37\\site-packages',
'C:\\anaconda3\\lib\\site-packages',
'C:\\anaconda3\\lib\\site-packages\\win32', 'C:\\anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\anaconda3\\lib\\site-packages\\Pythonwin']
如果我们要添加自己的搜索目录,有两种方法:
一是直接修改sys.path,添加要搜索的目录:
>>> import sys
>>> sys.path.append('/Users/michael/my_py_scripts')
这种方法是在运行时修改,运行结束后失效。
第二种方法是设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响。
【参考:类和实例 - 廖雪峰的官方网站】
class Student(object): def __init__(self, name, score): self.name = name self.score = score def get_grade(self): if self.score >= 90: return 'A' elif self.score >= 60: return 'B' else: return 'C' lisa = Student('Lisa', 99) bart = Student('Bart', 59) print(lisa.name, lisa.get_grade()) print(bart.name, bart.get_grade())
【参考:访问限制 - 廖雪峰的官方网站】
【参考:继承和多态 - 廖雪峰的官方网站】
当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。
【参考:获取对象信息 - 廖雪峰的官方网站】
基本类型都可以用type()判断:
isinstance()可以告诉我们,一个对象是否是某种类型
如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:
仅仅把属性和方法列出来是不够的,配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态:
>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'
19
【参考:实例属性和类属性 - 廖雪峰的官方网站】
实例属性属于各个实例所有,互不干扰;
类属性属于类所有,所有实例共享一个属性;
给实例绑定属性的方法是通过实例变量,或者通过self变量:
class Student(object):
def __init__(self, name):
self.name = name
s = Student('Bob')
s.score = 90
但是,如果Student类本身需要绑定一个属性呢?可以直接在class中定义属性,这种属性是类属性,归Student类所有:
class Student(object):
name = 'Student'
当我们定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到。
>>> class Student(object): ... name = 'Student' ... >>> s = Student() # 创建实例s >>> print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性 Student >>> print(Student.name) # 打印类的name属性 Student >>> s.name = 'Michael' # 给实例绑定name属性 >>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性 Michael >>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问 Student >>> del s.name # 如果删除实例的name属性 >>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了 Student
在编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性.
【参考:错误处理 - 廖雪峰的官方网站】
https://docs.python.org/3/library/exceptions.html#exception-hierarchy
【参考:调试 - 廖雪峰的官方网站】
凡是用print()来辅助查看的地方,都可以用断言(assert)来替代:
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n
def main():
foo('0')
assert的意思是,表达式n != 0应该是True,否则,根据程序运行的逻辑,后面的代码肯定会出错。
【参考:单元测试 - 廖雪峰的官方网站】
【参考:文档测试 - 廖雪峰的官方网站】
【参考:文件读写 - 廖雪峰的官方网站】
with语句来自动帮我们调用close()方法
【参考:StringIO和BytesIO - 廖雪峰的官方网站】
StringIO顾名思义就是在内存中读写str。
StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO
【参考:操作文件和目录 - 廖雪峰的官方网站】
【参考:序列化 - 廖雪峰的官方网站】
【参考:进程和线程 - 廖雪峰的官方网站】
【参考:正则表达式 - 廖雪峰的官方网站】
【参考:正则表达式 - 廖雪峰的官方网站】
【参考:常用内建模块 - 廖雪峰的官方网站】
【参考:常用第三方模块 - 廖雪峰的官方网站】
dict = {'Google': 'www.google.com', 'Runoob': 'www.runoob.com', 'taobao': 'www.taobao.com'}
print "字典值 : %s" % dict.items()
# 遍历字典列表
for key,values in dict.items():
print key,values
字典值 : [('Google', 'www.google.com'), ('taobao', 'www.taobao.com'), ('Runoob', 'www.runoob.com')]
Google www.google.com
taobao www.taobao.com
Runoob www.runoob.com
字符串是一个序列的Unicode字符,因此可以像其它序列,比如列表和元组(下一章会详细介绍两者)一样处理:
In [64]: s = 'python'
In [65]: list(s)
Out[65]: ['p', 'y', 't', 'h', 'o', 'n']
'separtor'.join(sequence) 参数说明 separtor:分隔符。可以为空 sequence:要连接的元素序列、字符串、元组、字典 上面的语法即:以separtor作为分隔符,将sequence所有的元素合并成一个新的字符串 返回值:返回一个以分隔符sep连接各个元素后生成的字符串 实例: seq3 = ('hello','good','boy','doiido') print(':'.join(seq3)) # hello:good:boy:doiido data={ "id":1000, "name":"Jack", "age":18 } keys=",".join(data.keys()) print(keys) # id,name,age
https://blog.csdn.net/MsSpark/article/details/86745391
with open'filename.txt','r',encode='utf-8') as f:
data_user=pd.read_csv(f) #文件的读操作
with open('data.txt','w',encode='utf-8') as f:
f.write('hello world') #文件的写操作
file对象属性
file.read([size]) 将文件数据作为字符串返回,可选参数size控制读取的字节数
file.readlines([size]) 返回文件中行内容的列表,size参数可选
file.write(str) 将字符串写入文件
file.writelines(strings) 将字符串序列写入文件
file.close() 关闭文件
file.closed 表示文件已经被关闭,否则为False
file.mode Access文件打开时使用的访问模式
file.encoding 文件所使用的编码
file.name 文件名
file.newlines 未读取到行分隔符时为None,只有一种行分隔符时为一个字符串,当文件有多种类型的行结束符时,则为一个包含所有当前所遇到的行结束的列表
file.softspace 为0表示在输出一数据后,要加上一个空格符,1表示不加。这个属性一般程序员用不着,由程序内部使用
【参考:定义函数 - 廖雪峰的官方网站】
如果没有return语句,函数执行完毕后也会返回结果,只是结果为None。return None可以简写为return
数据类型检查可以用内置函数isinstance()实现
def my_abs(x): if not isinstance(x, (int,float())): raise TypeError('类型有误') if x>=0: return x; elif x<0: return -x; print(my_abs(-1)) # 1 print(my_abs('x')) 1 Traceback (most recent call last): File "c:\Users\Jarvis\Desktop\Code\py\demo.py", line 10, in <module> print(my_abs('x')) File "c:\Users\Jarvis\Desktop\Code\py\demo.py", line 2, in my_abs if not isinstance(x, (int,float())): TypeError: isinstance() arg 2 must be a type or tuple of types
import math
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
# 在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值
return nx, ny
x, y = move(100, 100, 60, math.pi / 6)
print(x, y) # 151.96152422706632 70.0
r = move(100, 100, 60, math.pi / 6)
print(r) # (151.96152422706632, 70.0)
【参考:函数的参数 - 廖雪峰的官方网站】
一是必选参数在前,默认参数在后,否则Python的解释器会报错
默认参数必须指向不变对象!
也可以不按顺序提供部分默认参数。当不按顺序提供部分默认参数时,需要把参数名写上。比如调用enroll(‘Adam’, ‘M’, city=‘Tianjin’),意思是,city参数用传进去的值,其他默认参数继续使用默认值。
def enroll(name, gender, age=6, city='Beijing'):
print('name:', name)
print('gender:', gender)
print('age:', age)
print('city:', city)
enroll('Bob', 'M', 7)
enroll('Adam', 'M', city='Tianjin')
可变参数
# 在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
# 调用该函数时,可以传入任意个参数,包括0个参数
calc() # 0
calc((1,2,3)) # 6
nums = [1, 2, 3]
calc(*nums) # *nums表示把nums这个list的所有元素作为可变参数传进去。这种写法相当有用,而且很常见
只要定义类型的时候,实现__call__
函数,这个类型就成为可调用的
换句话说,我们可以把这个类型的对象当作函数来使用,相当于 重载了括号运算符
class Person():
def __init__(self, name, gender):
self.name = name
self.gender = gender
def __call__(self, friend):
print('My name is %s...' % self.name)
print('My friend is %s...' % friend)
B = Person('Jack','male')
B('Mark')
output:
My name is Jack
My friend is Mark
1.from 包名 import 函数名
from datatime import datatime
datetime.now()
2.import 函数名
import datetime
datetime.datetime.now()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。