python3:
python2:
python2 | python3 | 表现 | 转换 | 作用 |
---|---|---|---|---|
str | bytes | 字节 | encode | 存储、传输 |
unicode | str | 字符 | decode | 展示 |
例子:
# coding=utf-8
import six
import sys
def py2():
print(sys.getdefaultencoding())
str1 = u"1234hello world 你好世界"
print(type(str1))
print(str1)
print("-"*30)
with open("./ttt.jpg", 'rb') as f:
str2 = f.read()
print(type(str2))
print(str2[:30])
def py3():
print(sys.getdefaultencoding())
str1 = u"1234hello world 你好世界"
print(type(str1))
print(str1)
print("-"*30)
with open("./ttt.jpg", 'rb') as f:
str2 = f.read(100)
print(type(str2))
print(str2[:30])
if __name__ == "__main__":
if six.PY2:
py2()
if six.PY3:
py3()
例子:
# coding=utf-8
import six
import sys
def py2():
int_max = sys.maxint
print("max int:{}".format(int_max))
int1 = 9223372036854775807
print(type(int1), int1)
int2 = 9223372036854775808922337203685477580892233720368
print(type(int2), int2)
int3 = 928
print(type(int3), int3)
def py3():
# py3的sys没有maxint
# int_max = sys.maxint
# print("max int:{}".format(int_max))
int1 = 9223372036854775807
print(type(int1), int1)
int2 = 92233720368547758089999999999999999999999999223
print(type(int2), int2)
int3 = 928
print(type(int3), int3)
if __name__ == "__main__":
if six.PY2:
py2()
if six.PY3:
py3()
python3:
python2:
例子:
# coding=utf-8
import six
def py2():
dd={"a":1,"b":2, "hello":"world"}
print(dd.keys())
print(type(dd.keys()))
print("-"*10)
print(dd.values())
print(type(dd.values()))
print("-"*10)
print(dd.items())
print(type(dd.items()))
def py3():
dd={"a":1,"b":2, "hello":"world"}
print(dd.keys())
print(type(dd.keys()))
print("-"*10)
print(dd.values())
print(type(dd.values()))
print("-"*10)
print(dd.items())
print(type(dd.items()))
if __name__ == "__main__":
if six.PY2:
py2()
if six.PY3:
py3()
python3:
>>> True = 1
File "" , line 1
SyntaxError: can't assign to keyword
python2:
>>> True = False
>>> True
False
>>> True is False
True
>>> False = "x"
>>> False
'x'
>>> if False:
... print("yes")
...
yes
python3:
__next__
python2:
例子:
# coding=utf-8
import six
from collections import Iterable, Iterator
def func(x):
return x+1
class Iterpy2:
def __init__(self, data):
self.data = data # 上边界
self.now = 0 # 当前迭代值,初始为0
def __iter__(self):
return self # 返回该对象的迭代器类的实例;因为自己就是迭代器,所以返回self
def next(self): # 迭代器类必须实现的方法, 可迭代不用实现next
while self.now < self.data:
self.now += 1
return self.now - 1 # 返回当前迭代值
raise StopIteration # 超出上边界,抛出异常
def py2():
dd = {"a":1, "B":2, "hello":"world"}
print(type(dd.keys()))
print("-"*10)
print(type(dd.values()))
print("-"*10)
print(type(dd.items()))
print("#"*30)
# map
mm = map(func, [1,2,3,4,5])
print(mm, type(mm))
print("-"*10)
# filter
ff = filter(func, [1,2,3,4,5])
print(ff, type(ff))
print("-"*10)
# zip
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
zz = zip(a,b)
zz2 = zip(a,b,c)
print(zz, type(zz))
print(zz2, type(zz2))
print("#"*30)
# 迭代器
print(dir([]))
print(isinstance([], Iterable)) # __iter__
print(isinstance([], Iterator))
# list、dict、str虽然是Iterable(可迭代),却不是Iterator(迭代器)
print
it = iter(a)
try:
print(next(it))
except Exception as e:
print(e)
for i in a:
pass
# for循环等价如下
while True:
try:
x = next(it)
print(x)
except StopIteration:
# 遇到StopIteration就退出循环
break
def py3():
dd = {"a":1, "B":2, "hello":"world"}
print(type(dd.keys()))
print("-"*10)
print(type(dd.values()))
print("-"*10)
print(type(dd.items()))
print("#"*30)
# map
mm = map(func, [1,2,3,4,5])
print(mm, type(mm))
print("-"*10)
# filter
ff = filter(func, [1,2,3,4,5])
print(ff, type(ff))
print("-"*10)
# zip
a = [1,2,3]
b = [4,5,6]
c = [4,5,6,7,8]
zz = zip(a,b)
zz2 = zip(a,b,c)
print(zz, type(zz))
print(zz2, type(zz2))
print("#"*30)
# 迭代器
print(dir([]))
print(isinstance([], Iterable)) # __iter__
print(isinstance([], Iterator))
# list、dict、str虽然是Iterable(可迭代),却不是Iterator(迭代器)
print
it = iter(a)
try:
print(it.__next__())
except Exception as e:
print(e)
if __name__ == "__main__":
if six.PY2:
py2()
if six.PY3:
py3()
新式类:
旧式类(经典类):
# 子类访问父类的内容
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self):
print('%s会吃东西'%self.name)
class Student(Person):
def __init__(self,name,age,id):
# 第一种,父类名直接调用,这种方法什么地方都可以调用,与继承无关,并且需要写上对象本身
Person.__init__(self,name,age)
# 第二种,super(类名,对象本身),是python2内置的
super(Student,self).__init__(name,age)
# 第三种,python3做了优化可以内部不传参,推荐使用
super().__init__(name,age)
self.id = id
def eat(self):
super().eat() # 第三种方法在访问父类的方法
super(Student,self).eat() # 第二种方法在访问父类的方法
print('%s吃更好的东西'%self.name)
s1 = Student('sxc',18,188)
s1.eat()
python3:
>>> print("hello", "world")
('hello', 'world')
python2:
>>> print("hello", "world")
hello world
python2:
python3:
python3:
python2:
例子:
# coding=utf-8
import six
def py2():
# file(name[, mode[, buffering]])
f = file('test.txt')
print(f.read())
print(dir(f))
print(type(f))
print("#"*50)
f = file('ttt.jpg')
print(f.read(100))
print(dir(f))
print(type(f))
def py3():
# f = file('test.txt') # 报错
with open("./test.txt","r+") as f:
print(f.read())
print(dir(f))
print(type(f))
print("#"*50)
with open("./ttt.jpg","rb") as f:
print(f.read(100))
print(dir(f))
print(type(f))
if __name__ == "__main__":
if six.PY3:
py3()
if six.PY2:
py2()
官方文档: https://docs.python.org/zh-cn/3/reference/lexical_analysis.html#f-strings
python2:
python3:
In [1]: round(2.5)
Out[1]: 2
In [2]: round(3.5)
Out[2]: 4
In [3]: round(2.675, 2)
Out[3]: 2.67
In [1]: round(2.5)
Out[1]: 3.0
In [2]: round(3.5)
Out[2]: 4.0
In [3]: round(2.675, 2)
Out[3]: 2.67
In [x]: def func():
...: c = 1
...: def foo():
...: c=12
...: foo()
...: print(c)
...:
In [x]: func()
1
In [x]: def func():
...: c = 1
...: def foo():
...: nonlocal c
...: c=12
...: foo()
...: print(c)
...:
In [x]: func()
12
函数注解语法 可以在定义函数的时候对参数和返回值添加注解:
例如:
def foobar(a: int, b: "it's b", c: str = 5) -> tuple:
return a, b, c
a: int 这种是注解参数
c: str = 5 是注解有默认值的参数
-> tuple 是注解返回值。
注解的内容既可以是个类型也可以是个字符串,甚至表达式:
def funr(a: 1+1) -> 2 * 2:
return a
fun(3)
3
同时提供了获取定义的函数注解的两种办法:
>>> foobar.__annotations__
{'a': int, 'b': "it's b", 'c': str, 'return': tuple}
>>> import inspect
>>> sig = inspect.signature(foobar)
>>> # 获取函数参数
>>> sig.paraments
mappingproxy(OrderedDict([('a', <Parameter "a:int">), ('b', <Parameter "b:"it's b"">), ('c', <Parameter "c:str=5">)]))
>>> # 获取函数参数注解
>>> for k, v in sig.parameters.items():
print('{k}: {a!r}'.format(k=k, a=v.annotation))
a: <class 'int'>
b: "it's b"
c: <class 'str'>
>>> # 返回值注解
>> sig.return_annotation
tuple
Python 解释器并不会基于函数注解来自动进行类型检查, 所以就可以使用类型注解的方式对函数/方法进行类型检查
# coding: utf8
import collections
import functools
import inspect
def check(func):
msg = ('Expected type {expected!r} for argument {argument}, '
'but got type {got!r} with value {value!r}')
# 获取函数定义的参数
sig = inspect.signature(func)
parameters = sig.parameters # 参数有序字典
arg_keys = tuple(parameters.keys()) # 参数名称
@functools.wraps(func)
def wrapper(*args, **kwargs):
CheckItem = collections.namedtuple('CheckItem', ('anno', 'arg_name', 'value'))
check_list = []
# collect args *args 传入的参数以及对应的函数参数注解
for i, value in enumerate(args):
arg_name = arg_keys[i]
anno = parameters[arg_name].annotation
check_list.append(CheckItem(anno, arg_name, value))
# collect kwargs **kwargs 传入的参数以及对应的函数参数注解
for arg_name, value in kwargs.items():
anno = parameters[arg_name].annotation
check_list.append(CheckItem(anno, arg_name, value))
# check type
for item in check_list:
if not isinstance(item.value, item.anno):
error = msg.format(expected=item.anno, argument=item.arg_name,
got=type(item.value), value=item.value)
raise TypeError(error)
return func(*args, **kwargs)
return wrapper
@check
def foobar(a: int, b: str, c: float = 3.2) -> tuple:
return a, b, c
dataclass 可以为简单的情况自动生成方法,例如,一个__init__接受这些参数并将其分配给自己,之前的小例子可以重写为:
@dataclass
class MyClass:
var_a: str
var_b: str
@dataclasses.dataclass(*, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)
https://docs.python.org/zh-cn/3/library/dataclasses.html
https://six.readthedocs.io/
python2和python3都有
In [1]: import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
美胜于丑。
显式优于隐式。
简单胜于复杂。
复杂总比复杂好。
平滑的比嵌套的好。
稀疏胜于稠密。
可读性很重要。
特殊情况不足以打破规则。
尽管实用性胜过纯洁性。
错误永远不会悄悄地过去。
除非明确沉默。
面对歧义,拒绝猜测的诱惑。
应该有一种——最好只有一种——显而易见的方法来做到这一点。
不过,如果不是荷兰语的话,这种方式一开始可能并不明显。
现在总比没有好。
虽然从来没有比现在更好。
如果实现很难解释,那是个坏主意。
如果实现很容易解释,这可能是一个好主意。
名称空间是一个非常好的主意——让我们做更多的事情吧!