python零碎的注意
返回多个值/返回元组
a=1
b=2
a,b=b,a
print(a,b)
结果:
2 1
lambda表格即为一种临时使用的匿名函数,你懒得再写一个函数而使用的。一般来说应为比较简单的函数(当然你也可以用lambda表格写一个复杂的函数,但这样并不推荐。)
列表推导:
listone=[2,3,4]
listtwo=[2*i for i in listone if i>2]
print(listtwo)
结果:
[6, 8]
断言:
mylist=['item']
assert len(mylist)>=1
mylist.pop()
assert len(mylist)>=1
结果:
Traceback (most recent call last):
File "C:/Users/baili/PycharmProjects/new/base.py", line 37, in <module>
assert len(mylist)>=1
AssertionError
函数加不加括号:
函数不加括号仅有函数名表示该函数的地址,加括号表示函数。
把函数赋值给一个变量时不加括号即把函数关系赋给变量,可以把新的变量直接当函数使用。而此时加括号则新变量不能当函数使用了,即使括号内并没有需要的参数也不能当成函数使用。在使用isinstance函数判断Iterable时也要加了括号的可迭代函数才能返回true,否则不带括号即使是可迭代函数也依然返回false。
def add(x,y):
print(x+y)
q=add
q(3,4)
w=add()
w(3,4)
结果:
7
Traceback (most recent call last):
File "C:/Users/baili/PycharmProjects/agrith/iterable.py", line 22, in <module>
w=add()
TypeError: add() missing 2 required positional arguments: 'x' and 'y'
另:
from collections import Iterable
print(isinstance([],Iterable))
class Mylist(object):
def __init__(self):
self.list=[]
def add(self,item):
self.list.append(item)
def __iter__(self):
pass
mylist=Mylist()
print(isinstance(Mylist,Iterable))
print(isinstance(Mylist(),Iterable))
print(isinstance(mylist,Iterable))
结果:
True
C:/Users/baili/PycharmProjects/agrith/iterable.py:1: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
from collections import Iterable
False
True
True
self即c中的this指针
items()方法:
dic={'a':1,
'b':'rang',
'c':6}
#print(items(dic))
print(dic.items())
注释掉的部分是思想出现了问题,没有认识到python是面向对象的。items()方法是字典的
结果:
dict_items([('a', 1), ('b', 'rang'), ('c', 6)])
自定义可迭代类:
class Mylist(object):
def __init__(self):
self.items=[]
self.current=0
def add(self,val):
self.items.append(val)
def __next__(self):
if self.current<len(self.items):
item=self.items[self.current]
self.current+=1
return item
else:
raise StopIteration
def __iter__(self):
return self
if __name__=='__main__':
mylist=Mylist()
mylist.add(1)
mylist.add(2)
mylist.add(3)
mylist.add(4)
mylist.add(5)
for num in mylist:
print(num)
可迭代对象本身就是一个迭代器(iterater)。迭代器需要'__iter__'方法和'__next__'方法,以此满足迭代器协议(__next__())和可迭代协议(__iter__())。
_xxx :保护变量,意思是只有类对象和子类对象能够访问到这些变量(尽量避免在类外部直接修改)
__xxx__ :系统定义名字
__xxx :类中的私有变量名
切片[10:]为后十个数
l=[]
for i in range(1,10):
#l[i]=i*i
l.append(i*i)
print(l)
注释部分思想出现了问题,python中的for循环抽象度很高,和c没有可比性。
列表生成式:
print([x*x for x in range(1,10)])
print([m+n for m in 'asd' for n in 'lkj'])
结果:
[1, 4, 9, 16, 25, 36, 49, 64, 81]
['al', 'ak', 'aj', 'sl', 'sk', 'sj', 'dl', 'dk', 'dj']
简化代码,但一般就用到二重循环,更高还是要写代码来循环。
生成器(generater):对比列表生成式就是把[]改为()即可,事实上,生成器是一种特殊的迭代器,因此在我们定义生成器的时候其实就隐式地实现了__iter__()方法和__next__()方法而不用我们自己显式地实现,说到底生成器只是为了方便我们迭代而出现的。
print((x*x for x in range(1,10)))
print((m+n for m in 'asd' for n in 'lkj'))
结果:
<generator object <genexpr> at 0x000002448C44B480>
<generator object <genexpr> at 0x000002448C44B480>
对比这两个结果易于发现不同。那么如果我们需要输出生成器中的每个元素,我们可以选择不断调用next()方法,但更常用的是在for循环中使用它,因为python中for循环结果是一种高度抽象的结构,它可以隐式地使用next()方法而输出每一个元素,显然for结构的代码会简单许多。
事实上,函数体中包含yield方法的即为生成器,它与普通的函数在执行的过程中有很大的不同。生成器函数中yield为返回指令而非return。且是挂起结果。
super()方法:就是一种在子类中调用父类的方法。
注意:
for count in [1:]:
print(next(I))
错误,应为:
class Iter:
def __init__(self):
self.start=-1
def __iter__(self):
return self
def __next__(self):
self.start +=2
return self.start
I = Iter()
for count in range(5):
print(next(I))
结果:
1
3
5
7
9
上面这个为输出奇数的迭代器实现,下面给出生成器实现:
def odd():
n=1
while True:
yield n
n+=2
odd_num = odd()
count = 0
for o in odd_num:
if count >=5: break
print(o)
count +=1
进一步学习迭代器:
class Counter:
def __init__(self):
self.index = 0
def __next__(self):
i = self.index
if i < 10:
self.index += 1
return i
else:
raise StopIteration
counter = Counter()
for i in counter:
print(i)
输出报错!因为此时你的的确确实现了一个迭代器,但这个迭代器自身不能迭代,因此这其实仅仅是一个迭代器但却没有任何用处。而造成这一错误的原因就是该段代码仅仅遵循了 迭代器协议(__next__()) 即这的的确确是一个迭代器,但却并没有遵循可迭代协议(__iter__())。因此它会报错。
改进后:
class Counter:
def __init__(self):
self.index = 0
def __iter__(self):
return self
def __next__(self):
i = self.index
if i < 10:
self.index += 1
return i
else:
raise StopIteration
counter = Counter()
for i in counter:
print(i)
输出结果:
0
1
2
3
4
5
6
7
8
9
在满足了迭代器协议(__next__())以及可迭代协议(__iter__())后输出正常。
“可迭代”和“迭代器”本身就是两码事。
事实上我们可以让普通的其他对象迭代而不一定非要是迭代器。
k=[1,2,3]
k.__next__()
报错,说明其实列表并不满足 迭代器协议,但我们清楚列表是可迭代的,满足可迭代协议。