输入输出重定向
test.py < command.txt > output.txt
Python技巧OR特性
Python 整洁之道
断言
assert expression1 expression2
当expression1
为F时,出发expression2
字符串输入的技巧
charTest = ("I am text 1,"
"I am text 2,"
"I am text 3")
print(charTest)
字符串会自动合并,将三段字符串全部合并。
巧妙地放置逗号
listTest = [1,
2,
3,
4
]
print(listTest)
下划线、双下划线(dunder)及其他
-
在类方法中,单下划线只是意义上的内部调用约定,实际没有影响
-
双下划线是放改写操作,其方法名称会改为_模块名__方法名。
-
变量名使用中,单下划线做为临时变量使用极为方便优雅。
```python
car = ('red', 'auto', 12, 3812.4)
color, _, _, mileage = car
print(color)
print(mileage)
print(_)
```
`_`作为Python REPL中的一个特殊变量。下划线也可以获取先前计算的值:
```python
20+3
print(_)
```
字符串
使用 ~f"我是第{first}名,他是第{second}名。"~ 来格式化字符串。
from string import Template
name = "June"
t = Template('Hey, $name!')
t = t.substitute(name=name)
print(t)
函数
特性
- Python中一切皆为对象,函数也不例外。可以将函数分配给变量或储存在数据结构之中。作为头等对象,函数还可以被传递给其他函数或作为其他函数的返回值。
- 头等函数的特性可以用来抽象并传递程序中的行为。
- 函数可以嵌套,并且可以捕获并携带父函数的一些状态。具有这种行为的函数成为闭包。
- 对象可以被设置为可调用的,因此很多情况下可以将其作为函数对待。(call)
lambda
- lambda函数是单表达式的函数,不必与名称绑定。
- lambda函数不能使用普通的Python语句,其中总是包含一个隐式return语句。
- 使用前总是先问问自己: *使用普通具名函数者或者列表解析式是否更加清晰。
装饰器
一个Python教程写的好不好,看其中对装饰器的讲解就能知道了。
- 装饰器用于定义可重用的组件,可以将其应用与可调用对象以修改其行为,同时无需永久修改可调用对象本身。
- @语法只是在输入函数爽调用装饰器的简写。在单个函数上应用多个装饰器的顺序是从底部到顶部(装饰器栈)。
- 为了方便调试,最好在自己的装饰器中使用
functools.wraps
将被装饰对象中的元素数据转移到修饰后的对象中。
类与面向对象
在定义类时添加 __repr__
属性, python2中是 __unicode__
方法
class Car:
def __init__(self, color, mileage):
self.color = color
self.mileage = mileage
def __repr__(self):
return (f'{self.__class__.__name__}('
f'{self.color!r}, {self.mileage!r})')
z = Car("Red", 37281)
print(z)
定义自己的异常类
class NameTooShortError(ValueError):
pass
def validate(name):
if len(name) < 10:
raise NameTooShortError(name)
validate("Jane")
Traceback (most recent call last):
File “”, line 8, in
File “”, line 6, in validate
__main__.NameTooShortError: Jane
克隆对象来做测试
import copy
_ = [0,1,2,3]
class A:
pass
a = list(_)
print(_ is a)
b = copy.copy(_)
print(_ is b)
c1 = A()
c2 = copy.deepcopy(A)
print(c1 is c2)
namedtuple
pass
类变量
- 类变量用于类的所有实例之间共享数据,类变量属于一个类,在类的所有实例中共享,而不是属于某个特定的实例。
- 类变量都是特定于每个实例的数据,属于单个对象实例,在类的其他实例共享。每个实例变量都针对特定实例单独储存了一份。
- 因为类变量可以被同名的实例变量「遮盖」,所以很容易(意外地)由于覆盖类变量而引入 bug 和奇怪的行为。
实例方法、类方法和静态方法
- 实例方法需要一个类实例,可以通过 self 访问实例。
- 类方法不需要实例,不能访问实例(self),但可以通过cls访问类本身。也就是说,在没有实例的时候,就可以调用的方法,该方法可以调用类本身进行实例化。
- 静态方法不能访问cls,或self,其作用和普通函数相同,单属于类的名称空间。
- 静态方法和类方法能(在一定程度上)展示和贯彻开发人员对类的设计意图,有助于代码维护。
@classmethod @staticmethod
数据结构
栈
collections.deque
是比较好的通用栈实现。
优雅的循环和美丽的迭代器
解析式
print([i*i for i in range(-9,10)
if i % 2 == 0 ])
print({i:i*i for i in range(-9,10)
if i % 2 == 0})
print({i*i for i in range(-9,10)
if i % 2 == 0})
列表的切片
z = [i for i in range(100)]
print(z,z[::-1],z[::2],z[::-2],sep="\n")
迭代器
- 生成迭代器
<a id="code-snippet--iter"></a>
```python
z = [i for i in range(100)]
z_iter = iter(z)
for i in range(5):
print("用iter生成器生成的迭代器:",next(z_iter),sep=" ")
z_iter2 = (i for i in range(100))
for i in range(5):
print("用解析式生成的迭代器:",next(z_iter2),sep=" ")
class egIter:
def __init__(self,maxIter):
self.maxIter = maxIter
self.count = 0
def __iter__(self):
return self
def __next__(self):
if self.count >= self.maxIter:
raise StopIteration
self.count += 1
return self.count
z_iter3 = egIter(10)
for i in range(100):
try:
print("这里是类定义的迭代器",next(z_iter3),sep=" ")
except StopIteration:
break
```