【长文】一篇文章,一整天coding,带你入门python

最近有许多小伙伴后台联系我,说目前想要学习Python,但是没有一份很好的资料入门。一方面的确现在市面上Python的资料过多,导致新手会不知如何选择,另一个问题很多资料内容也很杂,从1+1到深度学习都包括,纯粹关注Python本身语法的优质教材并不太多。

注释

Python中用#表示单行注释,#之后的同行的内容都会被注释掉。

# Python中单行注释用#表示,#之后同行字符全部认为被注释。

使用三个连续的双引号表示多行注释,两个多行注释标识之间内容会被视作是注释。

""" 与之对应的是多行注释

用三个双引号表示,这两段双引号当中的内容都会被视作是注释

"""

基础变量类型与操作符

Python当中的数字定义和其他语言一样:

#获得一个整数

3

# 获得一个浮点数

10.0

我们分别使用+, -, *, /表示加减乘除四则运算符。

1 + 1   # => 2

8 - 1   # => 7

10 * 2  # => 20

35 / 5  # => 7.0

这里要注意的是,在Python2当中,10/3这个操作会得到3,而不是3.33333。因为除数和被除数都是整数,所以Python会自动执行整数的计算,帮我们把得到的商取整。如果是10.0 / 3,就会得到3.33333。目前Python2已经不再维护了,可以不用关心其中的细节。

但问题是Python是一个弱类型的语言,如果我们在一个函数当中得到两个变量,是无法直接判断它们的类型的。这就导致了同样的计算符可能会得到不同的结果,这非常蛋疼。以至于程序员在运算除法的时候,往往都需要手工加上类型转化符,将被除数转成浮点数。

在Python3当中拨乱反正,修正了这个问题,即使是两个整数相除,并且可以整除的情况下,得到的结果也一定是浮点数。

如果我们想要得到整数,我们可以这么操作:

5 // 3       # => 1

-5 // 3      # => -2

5.0 // 3.0   # => 1.0 # works on floats too

-5.0 // 3.0  # => -2.0

两个除号表示取整除,Python会为我们保留去除余数的结果。

除了取整除操作之外还有取余数操作,数学上称为取模,Python中用%表示。

# Modulo operation

7 % 3  # => 1

Python中支持乘方运算,我们可以不用调用额外的函数,而使用**符号来完成:

# Exponentiation (x**y, x to the yth power)

2**3  # => 8

当运算比较复杂的时候,我们可以用括号来强制改变运算顺序。

# Enforce precedence with parentheses

1 + 3 * 2  # => 7

(1 + 3) * 2  # => 8

逻辑运算

Python中用首字母大写的True和False表示真和假。

True  # => True

False  # => False

用and表示与操作,or表示或操作,not表示非操作。而不是C++或者是Java当中的&&, || 和!。

# negate with not

not True   # => False

not False  # => True

# Boolean Operators

# Note "and" and "or" are case-sensitive

True and False  # => False

False or True   # => True

在Python底层,True和False其实是1和0,所以如果我们执行以下操作,是不会报错的,但是在逻辑上毫无意义。

# True and False are actually 1 and 0 but with different keywords

True + True # => 2

True * 8    # => 8

False - 5   # => -5

我们用==判断相等的操作,可以看出来True==1, False == 0.

# Comparison operators look at the numerical value of True and False

== False  # => True

1 == True   # => True

2 == True   # => False

-5 != False # => True

我们要小心Python当中的bool()这个函数,它并不是转成bool类型的意思。如果我们执行这个函数,那么只有0会被视作是False,其他所有数值都是True

bool()     # => False

bool(4)     # => True

bool(-6)    # => True

and 2     # => 0

-5 or      # => -5

Python中用==判断相等,>表示大于,>=表示大于等于,

# Equality is ==

1 == 1  # => True

2 == 1  # => False

# Inequality is !=

1 != 1  # => False

2 != 1  # => True

# More comparisons

1  True

1 > 10  # => False

2  True

2 >= 2  # => True

我们可以用and和or拼装各个比较操作:

# Seeing whether a value is in a range

# Chaining makes this look nicer

注意not,and,or之间的优先级,其中not > and > or。如果分不清楚的话,可以用括号强行改变运行顺序。

list和字符串

关于list的判断,我们常用的判断有两种,一种是刚才介绍的==,还有一种是is。我们有时候也会简单使用is来判断,那么这两者有什么区别呢?我们来看下面的例子:

a = [1, 2, 3, 4]  # Point a at a new list, [1, 2, 3, 4]

b = a             # Point b at what a is pointing to

b is a            # => True, a and b refer to the same object

b == a            # => True, a's and b's objects are equal

b = [1, 2, 3, 4]  # Point b at a new list, [1, 2, 3, 4]

b is a            # => False, a and b do not refer to the same object

b == a            # => True, a's and b's objects are equal

Python是全引用的语言,其中的对象都使用引用来表示。is判断的就是两个引用是否指向同一个对象,而==则是判断两个引用指向的具体内容是否相等。举个例子,如果我们把引用比喻成地址的话,is就是判断两个变量的是否指向同一个地址,比如说都是沿河东路XX号。而==则是判断这两个地址的收件人是否都叫张三。

显然,住在同一个地址的人一定都叫张三,但是住在不同地址的两个人也可以都叫张三,也可以叫不同的名字。所以如果a is b,那么a == b一定成立,反之则不然。

Python当中对字符串的限制比较松,双引号和单引号都可以表示字符串,看个人喜好使用单引号或者是双引号。我个人比较喜欢单引号,因为写起来方便。

字符串也支持+操作,表示两个字符串相连。除此之外,我们把两个字符串写在一起,即使没有+,Python也会为我们拼接:

# Strings are created with " or '

"This is a string."

'This is also a string.'

# Strings can be added too! But try not to do this.

"Hello " + "world!"  # => "Hello world!"

# String literals (but not variables) can be concatenated without using '+'

"Hello " "world!"    # => "Hello world!"

我们可以使用[]来查找字符串当中某个位置的字符,用len来计算字符串的长度。

# A string can be treated like a list of characters

"This is a string"[]  # => 'T'

# You can find the length of a string

len("This is a string")  # => 16

我们可以在字符串前面加上f表示格式操作,并且在格式操作当中也支持运算。不过要注意,只有Python3.6以上的版本支持f操作。

# You can also format using f-strings or formatted string literals (in Python 3.6+)

name = "Reiko"

f"She said her name is ." # => "She said her name is Reiko"

# You can basically put any Python statement inside the braces and it will be output in the string.

f" is  characters long." # => "Reiko is 5 characters long."

最后是None的判断,在Python当中None也是一个对象,所有为None的变量都会指向这个对象。根据我们前面所说的,既然所有的None都指向同一个地址,我们需要判断一个变量是否是None的时候,可以使用is来进行判断,当然用==也是可以的,不过我们通常使用is。

# None is an object

None  # => None

# Don't use the equality "==" symbol to compare objects to None

# Use "is" instead. This checks for equality of object identity.

"etc" is None  # => False

None is None   # => True

理解了None之后,我们再回到之前介绍过的bool()函数,它的用途其实就是判断值是否是空。所有类型的默认空值会被返回False,否则都是True。比如0,“”,[], {}, ()等。

# None, 0, and empty strings/lists/dicts/tuples all evaluate to False.

# All other values are True

bool(None)# => False

bool()   # => False

bool("")  # => False

bool([])  # => False

bool({})  # => False

bool(())  # => False

除了上面这些值以外的所有值传入都会得到True。

变量与集合

输入输出

Python当中的标准输入输出是input和print

print会输出一个字符串,如果传入的不是字符串会自动调用__str__方法转成字符串进行输出。默认输出会自动换行,如果想要以不同的字符结尾代替换行,可以传入end参数:

# Python has a print function

print("I'm Python. Nice to meet you!")  # => I'm Python. Nice to meet you!

# By default the print function also prints out a newline at the end.

# Use the optional argument end to change the end string.

print("Hello, World", end="!")  # => Hello, World!

使用input时,Python会在命令行接收一行字符串作为输入。可以在input当中传入字符串,会被当成提示输出:

# Simple way to get input data from console

input_string_var = input("Enter some data: ") # Returns the data as a string

# Note: In earlier versions of Python, input() method was named as raw_input()

变量

Python中声明对象不需要带上类型,直接赋值即可,Python会自动关联类型,如果我们使用之前没有声明过的变量则会出发NameError异常。

# There are no declarations, only assignments.

# Convention is to use lower_case_with_underscores

some_var = 5

some_var  # => 5

# Accessing a previously unassigned variable is an exception.

# See Control Flow to learn more about exception handling.

some_unknown_var  # Raises a NameError

Python支持三元表达式,但是语法和C++不同,使用if else结构,写成:

# if can be used as an expression

# Equivalent of C's '?:' ternary operator

"yahoo!" if 3 > 2 else 2  # => "yahoo!"

上段代码等价于:

if 3 > 2:

return 'yahoo'

else:

return 2

list

Python中用[]表示空的list,我们也可以直接在其中填充元素进行初始化:

# Lists store sequences

li = []

# You can start with a prefilled list

other_li = [4, 5, 6]

使用append和pop可以在list的末尾插入或者删除元素:

# Add stuff to the end of a list with append

li.append(1)    # li is now [1]

li.append(2)    # li is now [1, 2]

li.append(4)    # li is now [1, 2, 4]

li.append(3)    # li is now [1, 2, 4, 3]

# Remove from the end with pop

li.pop()        # => 3 and li is now [1, 2, 4]

# Let's put it back

li.append(3)    # li is now [1, 2, 4, 3] again.

list可以通过[]加上下标访问指定位置的元素,如果是负数,则表示倒序访问。-1表示最后一个元素,-2表示导数第二个,以此类推。如果访问的元素超过数组长度,则会触发IndexError的错误。

# Access a list like you would any array

li[]   # => 1

# Look at the last element

li[-1]  # => 3

# Looking out of bounds is an IndexError

li[4]  # Raises an IndexError

list支持切片操作,所谓的切片则是从原list当中拷贝出指定的一段。我们用start: end的格式来获取切片,注意,这是一个左闭右开区间。如果留空表示全部获取,我们也可以额外再加入一个参数表示步长,比如[1:5:2]表示从1号位置开始,步长为2获取元素。得到的结果为[1, 3]。如果步长设置成-1则代表反向遍历。

# You can look at ranges with slice syntax.

# The start index is included, the end index is not

# (It's a closed/open range for you mathy types.)

li[1:3]   # Return list from index 1 to 3 => [2, 4]

li[2:]    # Return list starting from index 2 => [4, 3]

li[:3]    # Return list from beginning until index 3  => [1, 2, 4]

li[::2]   # Return list selecting every second entry => [1, 4]

li[::-1]  # Return list in reverse order => [3, 4, 2, 1]

# Use any combination of these to make advanced slices

# li[start:end:step]

如果我们要指定一段区间倒序,则前面的start和end也需要反过来,例如我想要获取[3: 6]区间的倒叙,应该写成[6:3:-1]。

只写一个:,表示全部获取,可以使用del删除指定位置的元素,或者可以使用remove方法。

# Make a one layer deep copy using slices

li2 = li[:]  # => li2 = [1, 2, 4, 3] but (li2 is li) will result in false.

# Remove arbitrary elements from a list with "del"

del li[2]  # li is now [1, 2, 3]

# Remove first occurrence of a value

li.remove(2)  # li is now [1, 3]

li.remove(2)  # Raises a ValueError as 2 is not in the list

insert方法可以执行指定位置插入元素,index方法可以查询某个元素第一次出现的下标。

# Insert an element at a specific index

li.insert(1, 2)  # li is now [1, 2, 3] again

# Get the index of the first item found matching the argument

li.index(2)  # => 1

li.index(4)  # Raises a ValueError as 4 is not in the list

list可以进行加法运算,两个list相加表示list当中的元素合并。等价于使用extend方法:

# You can add lists

# Note: values for li and for other_li are not modified.

li + other_li  # => [1, 2, 3, 4, 5, 6]

# Concatenate lists with "extend()"

li.extend(other_li)  # Now li is [1, 2, 3, 4, 5, 6]

我们想要判断元素是否在list中出现,可以使用in关键字,通过使用len计算list的长度:

# Check for existence in a list with "in"

1 in li  # => True

# Examine the length with "len()"

len(li)  # => 6

tuple

tuple和list非常接近,tuple通过()初始化。和list不同,tuple是不可变对象。也就是说tuple一旦生成不可以改变。如果我们修改tuple,会引发TypeError异常。

# Tuples are like lists but are immutable.

tup = (1, 2, 3)

tup[]      # => 1

tup[] = 3  # Raises a TypeError

由于小括号是有改变优先级的含义,所以我们定义单个元素的tuple,末尾必须加上逗号,否则会被当成是单个元素:

# Note that a tuple of length one has to have a comma after the last element but

# tuples of other lengths, even zero, do not.

type((1))   # => 

type((1,))  # => 

type(())    # => 

tuple支持list当中绝大部分操作:

# You can do most of the list operations on tuples too

len(tup)         # => 3

tup + (4, 5, 6)  # => (1, 2, 3, 4, 5, 6)

tup[:2]          # => (1, 2)

2 in tup         # => True

我们可以用多个变量来解压一个tuple:

# You can unpack tuples (or lists) into variables

a, b, c = (1, 2, 3)  # a is now 1, b is now 2 and c is now 3

# You can also do extended unpacking

a, *b, c = (1, 2, 3, 4)  # a is now 1, b is now [2, 3] and c is now 4

# Tuples are created by default if you leave out the parentheses

d, e, f = 4, 5, 6  # tuple 4, 5, 6 is unpacked into variables d, e and f

# respectively such that d = 4, e = 5 and f = 6

# Now look how easy it is to swap two values

e, d = d, e  # d is now 5 and e is now 4

解释一下这行代码:

a, *b, c = (1, 2, 3, 4)  # a is now 1, b is now [2, 3] and c is now 4

我们在b的前面加上了星号,表示这是一个list。所以Python会在将其他变量对应上值的情况下,将剩下的元素都赋值给b。

补充一点,tuple本身虽然是不可变的,但是tuple当中的可变元素是可以改变的。比如我们有这样一个tuple:

a = (3, [4])

我们虽然不能往a当中添加或者删除元素,但是a当中含有一个list,我们可以改变这个list类型的元素,这并不会触发tuple的异常:

a[1].append() # 这是合法的

dict

dict也是Python当中经常使用的容器,它等价于C++当中的map,即存储key和value的键值对。我们用{}表示一个dict,用:分隔key和value。

# Dictionaries store mappings from keys to values

empty_dict = {}

# Here is a prefilled dictionary

filled_dict = {"one": 1, "two": 2, "three": 3}

dict的key必须为不可变对象,所以list和dict不可以作为另一个dict的key,否则会抛出异常:

# Note keys for dictionaries have to be immutable types. This is to ensure that

# the key can be converted to a constant hash value for quick look-ups.

# Immutable types include ints, floats, strings, tuples.

invalid_dict = {[1,2,3]: "123"}  # => Raises a TypeError: unhashable type: 'list'

valid_dict = {(1,2,3):[1,2,3]}   # Values can be of any type, however.

我们同样用[]查找dict当中的元素,我们传入key,获得value,等价于get方法。

# Look up values with []

filled_dict["one"]  # => 1

filled_dict.get('one') #=> 1

我们可以call dict当中的keys和values方法,获取dict当中的所有key和value的集合,会得到一个list。在Python3.7以下版本当中,返回的结果的顺序可能和插入顺序不同,在Python3.7及以上版本中,Python会保证返回的顺序和插入顺序一致:

# Get all keys as an iterable with "keys()". We need to wrap the call in list()

# to turn it into a list. We'll talk about those later.  Note - for Python

# versions 

# not match the example below exactly. However, as of Python 3.7, dictionary

# items maintain the order at which they are inserted into the dictionary.

list(filled_dict.keys())  # => ["three", "two", "one"] in Python 

list(filled_dict.keys())  # => ["one", "two", "three"] in Python 3.7+

# Get all values as an iterable with "values()". Once again we need to wrap it

# in list() to get it out of the iterable. Note - Same as above regarding key

# ordering.

list(filled_dict.values())  # => [3, 2, 1]  in Python 

list(filled_dict.values())  # => [1, 2, 3] in Python 3.7+

我们也可以用in判断一个key是否在dict当中,注意只能判断key。

# Check for existence of keys in a dictionary with "in"

"one" in filled_dict  # => True

1 in filled_dict      # => False

如果使用[]查找不存在的key,会引发KeyError的异常。如果使用get方法则不会引起异常,只会得到一个None

# Looking up a non-existing key is a KeyError

filled_dict["four"]  # KeyError

# Use "get()" method to avoid the KeyError

filled_dict.get("one")      # => 1

filled_dict.get("four")     # => None

# The get method supports a default argument when the value is missing

filled_dict.get("one", 4)   # => 1

filled_dict.get("four", 4)  # => 4

setdefault方法可以为不存在的key插入一个value,如果key已经存在,则不会覆盖它:

# "setdefault()" inserts into a dictionary only if the given key isn't present

filled_dict.setdefault("five", 5)  # filled_dict["five"] is set to 5

filled_dict.setdefault("five", 6)  # filled_dict["five"] is still 5

我们可以使用update方法用另外一个dict来更新当前dict,比如a.update(b)。对于a和b交集的key会被b覆盖,a当中不存在的key会被插入进来:

# Adding to a dictionary

filled_dict.update({"four":4})  # => {"one": 1, "two": 2, "three": 3, "four": 4}

filled_dict["four"] = 4         # another way to add to dict

我们一样可以使用del删除dict当中的元素,同样只能传入key。

Python3.5以上的版本支持使用**来解压一个dict:

{'a': 1, **{'b': 2}}  # => {'a': 1, 'b': 2}

{'a': 1, **{'a': 2}}  # => {'a': 2}

set

set是用来存储不重复元素的容器,当中的元素都是不同的,相同的元素会被删除。我们可以通过set(),或者通过{}来进行初始化。注意当我们使用{}的时候,必须要传入数据,否则Python会将它和dict弄混。

# Sets store ... well sets

empty_set = set()

# Initialize a set with a bunch of values. Yeah, it looks a bit like a dict. Sorry.

some_set = {1, 1, 2, 2, 3, 4}  # some_set is now

set当中的元素也必须是不可变对象,因此list不能传入set。

# Similar to keys of a dictionary, elements of a set have to be immutable.

invalid_set = {[1], 1}  # => Raises a TypeError: unhashable type: 'list'

valid_set = {(1,), 1}

可以调用add方法为set插入元素:

# Add one more item to the set

filled_set = some_set

filled_set.add(5)  # filled_set is now

# Sets do not have duplicate elements

filled_set.add(5)  # it remains as before

set还可以被认为是集合,所以它还支持一些集合交叉并补的操作。

# Do set intersection with &

# 计算交集

other_set = {3, 4, 5, 6}

filled_set & other_set  # =>

# Do set union with |

# 计算并集

filled_set | other_set  # =>

# Do set difference with -

# 计算差集

{1, 2, 3, 4} - {2, 3, 5}  # =>

# Do set symmetric difference with ^

# 这个有点特殊,计算对称集,也就是去掉重复元素剩下的内容

{1, 2, 3, 4} ^ {2, 3, 5}  # =>

set还支持超集和子集的判断,我们可以用大于等于和小于等于号判断一个set是不是另一个的超集或子集:

# Check if set on the left is a superset of set on the right

{1, 2} >= {1, 2, 3} # => False

# Check if set on the left is a subset of set on the right

{1, 2}  True

和dict一样,我们可以使用in判断元素在不在set当中。用copy可以拷贝一个set。

# Check for existence in a set with in

2 in filled_set   # => True

10 in filled_set  # => False

# Make a one layer deep copy

filled_set = some_set.copy()  # filled_set is

filled_set is some_set        # => False

控制流和迭代

判断语句

Python当中的判断语句非常简单,并且Python不支持switch,所以即使是多个条件,我们也只能罗列if-else

# Let's just make a variable

some_var = 5

# Here is an if statement. Indentation is significant in Python!

# Convention is to use four spaces, not tabs.

# This prints "some_var is smaller than 10"

if some_var > 10:

print("some_var is totally bigger than 10.")

elif some_var 

print("some_var is smaller than 10.")

else:                  # This is optional too.

print("some_var is indeed 10.")

循环

我们可以用in来循环迭代一个list当中的内容,这也是Python当中基本的循环方式。

"""

For loops iterate over lists

prints:

dog is a mammal

cat is a mammal

mouse is a mammal

"""

for animal in ["dog", "cat", "mouse"]:

# You can use format() to interpolate formatted strings

print("{} is a mammal".format(animal))

如果我们要循环一个范围,可以使用range。range加上一个参数表示从0开始的序列,比如range(10),表示[0, 10)区间内的所有整数:

"""

"range(number)" returns an iterable of numbers

from zero to the given number

prints:

0

1

2

3

"""

for i in range(4):

print(i)

如果我们传入两个参数,则代表迭代区间的首尾

"""

"range(lower, upper)" returns an iterable of numbers

from the lower number to the upper number

prints:

4

5

6

7

"""

for i in range(4, 8):

print(i)

如果我们传入第三个元素,表示每次循环变量自增的步长

"""

"range(lower, upper, step)" returns an iterable of numbers

from the lower number to the upper number, while incrementing

by step. If step is not indicated, the default value is 1.

prints:

4

6

"""

for i in range(4, 8, 2):

print(i)

如果使用enumerate函数,可以同时迭代一个list的下标和元素

"""

To loop over a list, and retrieve both the index and the value of each item in the list

prints:

0 dog

1 cat

2 mouse

"""

animals = ["dog", "cat", "mouse"]

for i, value in enumerate(animals):

print(i, value)

while循环和C++类似,当条件为True时执行,为false时退出。并且判断条件不需要加上括号:

"""

While loops go until a condition is no longer met.

prints:

0

1

2

3

"""

x =

while x 

print(x)

x += 1  # Shorthand for x = x + 1

捕获异常

Python当中使用try和except捕获异常,我们可以在except后面限制异常的类型。如果有多个类型可以写多个except,还可以使用else语句表示其他所有的类型。finally语句内的语法无论是否会触发异常都必定执行

# Handle exceptions with a try/except block

try:

# Use "raise" to raise an error

raise IndexError("This is an index error")

except IndexError as e:

pass                 # Pass is just a no-op. Usually you would do recovery here.

except (TypeError, NameError):

pass                 # Multiple exceptions can be handled together, if required.

else:                    # Optional clause to the try/except block. Must follow all except blocks

print("All good!")   # Runs only if the code in try raises no exceptions

finally:                 #  Execute under all circumstances

print("We can clean up resources here")

with操作

在Python当中我们经常会使用资源,最常见的就是open打开一个文件。我们打开了文件句柄就一定要关闭,但是如果我们手动来编码,经常会忘记执行close操作。并且如果文件异常,还会触发异常。这个时候我们可以使用with语句来代替这部分处理,使用with会自动在with块执行结束或者是触发异常时关闭打开的资源

以下是with的几种用法和功能:

# Instead of try/finally to cleanup resources you can use a with statement

# 代替使用try/finally语句来关闭资源

with open("myfile.txt") as f:

for line in f:

print(line)

# Writing to a file

# 使用with写入文件

contents = {"aa": 12, "bb": 21}

with open("myfile1.txt", "w+") as file:

file.write(str(contents))        # writes a string to a file

with open("myfile2.txt", "w+") as file:

file.write(json.dumps(contents)) # writes an object to a file

# Reading from a file

# 使用with读取文件

with open('myfile1.txt', "r+") as file:

contents = file.read()           # reads a string from a file

print(contents)

# print: {"aa": 12, "bb": 21}

with open('myfile2.txt', "r+") as file:

contents = json.load(file)       # reads a json object from a file

print(contents)

# print: {"aa": 12, "bb": 21}

可迭代对象

凡是可以使用in语句来迭代的对象都叫做可迭代对象,它和迭代器不是一个含义。这里只有可迭代对象的介绍,想要了解迭代器的具体内容,请移步传送门:

当我们调用dict当中的keys方法的时候,返回的结果就是一个可迭代对象。

# Python offers a fundamental abstraction called the Iterable.

# An iterable is an object that can be treated as a sequence.

# The object returned by the range function, is an iterable.

filled_dict = {"one": 1, "two": 2, "three": 3}

our_iterable = filled_dict.keys()

print(our_iterable)  # => dict_keys(['one', 'two', 'three']). This is an object that implements our Iterable interface.

# We can loop over it.

for i in our_iterable:

print(i)  # Prints one, two, three

我们不能使用下标来访问可迭代对象,但我们可以用iter将它转化成迭代器,使用next关键字来获取下一个元素。也可以将它转化成list类型,变成一个list。

# However we cannot address elements by index.

our_iterable[1]  # Raises a TypeError

# An iterable is an object that knows how to create an iterator.

our_iterator = iter(our_iterable)

# Our iterator is an object that can remember the state as we traverse through it.

# We get the next object with "next()".

next(our_iterator)  # => "one"

# It maintains state as we iterate.

next(our_iterator)  # => "two"

next(our_iterator)  # => "three"

# After the iterator has returned all of its data, it raises a StopIteration exception

next(our_iterator)  # Raises StopIteration

# We can also loop over it, in fact, "for" does this implicitly!

our_iterator = iter(our_iterable)

for i in our_iterator:

print(i)  # Prints one, two, three

# You can grab all the elements of an iterable or iterator by calling list() on it.

list(our_iterable)  # => Returns ["one", "two", "three"]

list(our_iterator)  # => Returns [] because state is saved

函数

使用def关键字来定义函数,我们在传参的时候如果指定函数内的参数名,可以不按照函数定义的顺序传参:

# Use "def" to create new functions

def add(x, y):

print("x is {} and y is {}".format(x, y))

return x + y  # Return values with a return statement

# Calling functions with parameters

add(5, 6)  # => prints out "x is 5 and y is 6" and returns 11

# Another way to call functions is with keyword arguments

add(y=6, x=5)  # Keyword arguments can arrive in any order.

可以在参数名之前加上*表示任意长度的参数,参数会被转化成list:

# You can define functions that take a variable number of

# positional arguments

def varargs(*args):

return args

varargs(1, 2, 3)  # => (1, 2, 3)

也可以指定任意长度的关键字参数,在参数前加上**表示接受一个dict:

# You can define functions that take a variable number of

# keyword arguments, as well

def keyword_args(**kwargs):

return kwargs

# Let's call it to see what happens

keyword_args(big="foot", loch="ness")  # => {"big": "foot", "loch": "ness"}

当然我们也可以两个都用上,这样可以接受任何参数:

# You can do both at once, if you like

def all_the_args(*args, **kwargs):

print(args)

print(kwargs)

"""

all_the_args(1, 2, a=3, b=4) prints:

(1, 2)

{"a": 3, "b": 4}

"""

传入参数的时候我们也可以使用*和**来解压list或者是dict:

# When calling functions, you can do the opposite of args/kwargs!

# Use * to expand tuples and use ** to expand kwargs.

args = (1, 2, 3, 4)

kwargs = {"a": 3, "b": 4}

all_the_args(*args)            # equivalent to all_the_args(1, 2, 3, 4)

all_the_args(**kwargs)         # equivalent to all_the_args(a=3, b=4)

all_the_args(*args, **kwargs)  # equivalent to all_the_args(1, 2, 3, 4, a=3, b=4)

Python中的参数可以返回多个值

# Returning multiple values (with tuple assignments)

def swap(x, y):

return y, x  # Return multiple values as a tuple without the parenthesis.

# (Note: parenthesis have been excluded but can be included)

x = 1

y = 2

x, y = swap(x, y)     # => x = 2, y = 1

# (x, y) = swap(x,y)  # Again parenthesis have been excluded but can be included.

函数内部定义的变量即使和全局变量重名,也不会覆盖全局变量的值。想要在函数内部使用全局变量,需要加上global关键字,表示这是一个全局变量:

# Function Scope

x = 5

def set_x(num):

# Local var x not the same as global variable x

x = num    # => 43

print(x)   # => 43

def set_global_x(num):

global x

print(x)   # => 5

x = num    # global var x is now set to 6

print(x)   # => 6

set_x(43)

set_global_x(6)

Python支持函数式编程,我们可以在一个函数内部返回一个函数:

# Python has first class functions

def create_adder(x):

def adder(y):

return x + y

return adder

add_10 = create_adder(10)

add_10(3)   # => 13

Python中可以使用lambda表示匿名函数,使用:作为分隔,:前面表示匿名函数的参数,:后面的是函数的返回值:

# There are also anonymous functions

(lambda x: x > 2)(3)                  # => True

(lambda x, y: x ** 2 + y ** 2)(2, 1)  # => 5

我们还可以将函数作为参数使用map和filter,实现元素的批量处理和过滤。关于Python中map、reduce和filter的使用,具体可以查看之前的文章:

# There are built-in higher order functions

list(map(add_10, [1, 2, 3]))          # => [11, 12, 13]

list(map(max, [1, 2, 3], [4, 2, 1]))  # => [4, 2, 3]

list(filter(lambda x: x > 5, [3, 4, 5, 6, 7]))  # => [6, 7]

我们还可以结合循环和判断语来给list或者是dict进行初始化:

# We can use list comprehensions for nice maps and filters

# List comprehension stores the output as a list which can itself be a nested list

[add_10(i) for i in [1, 2, 3]]         # => [11, 12, 13]

[x for x in [3, 4, 5, 6, 7] if x > 5]  # => [6, 7]

# You can construct set and dict comprehensions as well.

# => {'d', 'e', 'f'}

# =>

模块

使用import语句引入一个Python模块,我们可以用.来访问模块中的函数或者是类。

# You can import modules

import math

print(math.sqrt(16))  # => 4.0

我们也可以使用from import的语句,单独引入模块内的函数或者是类,而不再需要写出完整路径。使用from import *可以引入模块内所有内容(不推荐这么干)

# You can get specific functions from a module

from math import ceil, floor

print(ceil(3.7))   # => 4.0

print(floor(3.7))  # => 3.0

# You can import all functions from a module.

# Warning: this is not recommended

from math import *

可以使用as给模块内的方法或者类起别名:

# You can shorten module names

import math as m

math.sqrt(16) == m.sqrt(16)  # => True

我们可以使用dir查看我们用的模块的路径:

# You can find out which functions and attributes

# are defined in a module.

import math

dir(math)

这么做的原因是如果我们当前的路径下也有一个叫做math的Python文件,那么会覆盖系统自带的math的模块。这是尤其需要注意的,不小心会导致很多奇怪的bug。

我们来看一个完整的类,相关的介绍都在注释当中

# We use the "class" statement to create a class

class Human:

# A class attribute. It is shared by all instances of this class

# 类属性,可以直接通过Human.species调用,而不需要通过实例

species = "H. sapiens"

# Basic initializer, this is called when this class is instantiated.

# Note that the double leading and trailing underscores denote objects

# or attributes that are used by Python but that live in user-controlled

# namespaces. Methods(or objects or attributes) like: __init__, __str__,

# __repr__ etc. are called special methods (or sometimes called dunder methods)

# You should not invent such names on your own.

# 最基础的构造函数

# 加了下划线的函数和变量表示不应该被用户使用,其中双下划线的函数或者是变量将不会被子类覆盖

# 前后都有双下划线的函数和属性是类当中的特殊属性

def __init__(self, name):

# Assign the argument to the instance's name attribute

self.name = name

# Initialize property

self._age =

# An instance method. All methods take "self" as the first argument

# 类中的函数,所有实例可以调用,第一个参数必须是self

# self表示实例的引用

def say(self, msg):

print(": ".format(name=self.name, message=msg))

# Another instance method

def sing(self):

return 'yo... yo... microphone check... one two... one two...'

# A class method is shared among all instances

# They are called with the calling class as the first argument

@classmethod

# 加上了注解,表示是类函数

# 通过Human.get_species来调用,所有实例共享

def get_species(cls):

return cls.species

# A static method is called without a class or instance reference

@staticmethod

# 静态函数,通过类名或者是实例都可以调用

def grunt():

return "*grunt*"

# A property is just like a getter.

# It turns the method age() into an read-only attribute of the same name.

# There's no need to write trivial getters and setters in Python, though.

@property

# property注解,类似于get,set方法

# 效率很低,除非必要,不要使用

def age(self):

return self._age

# This allows the property to be set

@age.setter

def age(self, age):

self._age = age

# This allows the property to be deleted

@age.deleter

def age(self):

del self._age

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200703A0D0HA00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券