false_value = [
[],
{},
False,
'',
0,
0.0,
None,
]
for x in false_value:
print(True if value else False)
正确返回None值
一个函数里面可能多个返回值都为True或False,这时候就要用is明确指定返回值,如None
if条件优化
'{}'.format
'%s'%()
f'I'm {age}'
推荐import this
可以打印python之禅[item for item in items if item%2 == 0]
a = [1, 2, 3, 4, 5, 6]
{item:str(item) for item in a}
{**d1, **d2, **d3}
推荐try-except
抛出异常 # 默认空返回None,也可以设置
d.get('name','unkown')
```推荐
from collection import defaultdict
d_new = defaultdict(lamda:'missing', d)
d_new['name'] # 返回name对应的
d_new['asdf'] # 不存在则返回missing
class A:
def __init__(self):
self.data = []
def add(self, x):
self.data.append(x)
def __iter__(self):
# return self.data.__iter__()
# 这里也可以加一个for循环
for item in self.data:
yield item
class B():
def __init__(self, x, y):
self.x = x
self.y = y
b1 = B(x=1, y=2)
b2 = B(x=3, y=4)
a = A()
a.add(b1)
a.add(b2)
for item in a:
print(item.x, item.y)
为什么要使用yield
一次性读取可能会占用太多内存,yield可以提高效率
如何在递归调用中使用yield
示例:
import os
path = ''
def get_file(folder_name):
for item in os.listdir(folder_name):
full_path = os.path.join(folder_name, item)
if os.path.isfile(full_path):
yield full_path
elif os.path.isdir(full_path):
# 方法一
for item in get_file(full_path):
yield item
# 方法二,python3
yield from get_file(full_path)
for file_name in get_file(path):
print(file_name)
巧用lambda
函数参数为函数时,可以考虑能否用lambda实现
Jupyter shift+tab可以查看信息,比如sort排序传入key
处理程序中的异常
try-except,可以具体抛出某些异常。
总的如except Exception as e:
具体的如except DNSError:
函数默认参数
为函数参数设置默认值
可变数量参数
def function(x, *args):
print(args)
function(1,2,3,4)
# 结果
[2, 3, 4]
# 注意: 使用```*args```之后,x就不能赋值了,否则会报错SyntaxError
# 当如下形式时,x必须赋值,否则会报错TypeError:
def function(*args, x):
print(args, x)
function(1,2,x=3)
**kwargs
的关系def function(x, **kwargs):
print(x, kwargs)
function(x=1, a=2, b=3, c=4)
# 运行结果
1 {'a':2, 'b':3, 'c':4}
def sum1(x, y):
print(x+y)
sum(x=1, y=2)
sum(**{'x':1, 'y':'2'})
传入参数```**{'x':1, 'y':2}```与传入参数```x=1, y=2```返回结果一样
def bad_default_arg(s, time, target=[]):
for _ in range(time):
target.append(a)
return target
bad_default_arg(s='a', time=3) # 返回 ['a', 'a', 'a']
bad_default_arg(s='b', time=3, target='a') # 返回 ['a', 'b', 'b', 'b']
bad_default_arg(s='AB', time=2) # 返回 ['a', 'a', 'a', 'AB', 'AB']
# 使用列表作为参数时,假如不指定,则会使用上一次的默认值
bad_default_arg(s='F', time=2) # 返回 ['a', 'a', 'a', 'AB', 'AB', 'F', 'F']
解决方法:
def good_default_arg(s, time, target=None):
if target is None:
target = []
for _ in range(time):
target.append(a)
return target
尽量避免使用from xxx import *
库中方法可能与已命名方法重名,建议用什么引入什么
合理使用virtualenv与pip
类的属性和实例属性
类实例的受保护属性和私有属性
class A(object):
"""docstring for A"""
def __init__(self, name, age):
super(A, self).__init__()
self.__name = name
self.__age = age
a = A(name='python', age=27)
a.__age # 无法被访问
class B:
def __init__(self, name, age):
self.__name = name
self.__age = age
@property
def name(self):
return self._name
@property
def age(self):
return self._age
@age.setter
def age(self, value):
self.__age = value
def __str__(self):
print('My name is {} and my age is {}'.format(self.__name, self.__age))
b = B('Demo', 30)
print(b)
b.age = 40 # 可以修改
a = [1, 2, 3, 4]
for item in enumerate(a):
print(item)
# 返回
(0,1)
(1,2)
(2,3)
(3,4)
import collections
Student = collections.namedtuple('Student', 'id, name, score')
students = [
Student(1, 'ABC', 90),
Student(2, 'XYZ', 85),
Student(3, 'asdf', 80)
]
# 调用
for s in students:
print('name={}, id={}, score={}'.format(s.name, s.id, s.score))
提高可读性及可维护性,效率并无太大区别
# 1
dict(a=1,b=2)
# 2
data = (('a':1), ('b':2)) # 只要是可迭代对象都行
dict(data)
# 3
# 两个元素数量相同的列表
dict(zip(x,y)) # 生成对应字典
字典按照key/value大小排序
dict(sorted(d.items(), key=lambda x:x[1], reverse=True))
通过debug学习Python生成器
yield生成器
string操作技巧
s = ' Last Checkpoint: a few seconds ago (unsaved changes) '
最好是链条式做完,而不是一个一个做
列表解析取代map和filter
上下文管理
with open
一个单独的下划线可以怎么用
__str__和__repr__
区别
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f'name={self.name}, age={self.age}'
def __repr__(self):
return f'name:{self.name}, age:{self.age}'
p = Person('Python', 27)
print(p) # 先找__str__没有再找__repr__,都没有打印地址
p # 命令行中输入p,有__repr__才能返回值,否则返回地址
from exception import NameTooShort
def validate(name):
if len(name) < 10:
raise NameTooShort('Name is too short.')
try:
validate('test')
except NameTooShort as e:
print(e)
# exceprion.py 文件下
class NameTooShort(ValueError):
pass
# 多个错误可以定义一个基类继承自Exception,其他错误都继承这个基类
def sum(x: int, y: int) -> int: # x、y都是int对象,函数返回int对象
return x + y
if __name__ == '__main__':
print(sum('1', '2')) # 并不会报错,用mypy会提示希望是int,但却是str类型
# python3.6+
from typing import NmaedTuple
class Car(NmaedTuple):
color: str
mileage: float
automatic: bool
# 以上类型只是建议,不用对应的类型也不会报错,mypy会报错
car = Car('red', '100.01', False)
car.mileage = 100 # 会报错,因为不支持修改数据
用哪种数据结构存储数据
Python3.7+ Data Class
from dataclasses import dataclass
@dataclass
class NewPeple:
name: str
age: int
# 仅仅是提示
p1 = NewPeple('A', 20)
p2 = NewPeple('A', 20)
print(p1, p2) # 普通类还要重写__str__ ,__repr__
print('p1=p2?', p1==p2) # 普通类需要重写__eq__