Python基础教程(第3版)》笔记:第6章抽象

**斐波那契数列:**每个数都是前两个数的和。

fibs = [0,1]
for i in range(8):fibs.append(fibs[-2]+fibs[-1])

运行此程序,fibs将包含前10个斐波那契数。

可以修改前述for循环,使其处理动态的范围,即让用户指定最终要得到的序列的长度。

fibs = [0, 1]
num = int(input('How many Fibonacci numbers do you want? '))
for i in range(num-2): fibs.append(fibs[-2] + fibs[-1])
print(fibs)

6.2 抽象和结构

抽象是程序能够被人理解的关键所在。

page = download_page()
freqs = compute_frequencies(page)
for word, freq in freqs: print(word, freq)

看到这些代码,任何人都知道这个程序是做什么的。然而,至于具体该如何做,你未置一词。你只是让计算机去下载网页并计算使用频率,至于这些操作的具体细节,将在其他地方(独立的函数定义)中给出。

6.3 自定义函数

可以调用函数执行特定的操作。

可使用内置函数callable判断某个对象是否可调用。

>>> import math
>>> x = 1
>>> y = math.sqrt
>>> callable(x)
False
>>> callable(y)
True 

使用def语句定义函数

>>> def hello(name):return 'Hello, ' + name + '!'>>> print(hello('uuuu'))
Hello, uuuu!

6.3.1 给函数编写文档

  • 可添加注释
  • 添加独立的字符串,如def语句后面,添加字符串,此字符串称为文档字符串(docstring),将作为函数的一部分存储起来。
def square(x): 'Calculates the square of the number x.' return x * x

访问文档字符串的方式:

>>> square.__doc__
'Calculates the square of the number x.'

注意:__doc__是函数的一个属性,


可使用特殊的内置函数help获取有关函数的信息

说明 函数可有可无return语句。

6.4 参数魔法

6.4.1 值从哪里来

函数要确保在提供的参数正确时完成任务,并在参数不对时以显而易见的方式失败。(为此,通常使用断言或异常。)

6.4.2 在函数内能修改参数吗

在函数内部给参数赋值对外部没有任何影响。

>>> def try_to_change(n):n = 'mr'
>>> name = 'Mrs'
>>> try_to_change(name)
>>> name
'Mrs'

字符串、数和元组是不可变的(immutable),只能替换为新值。但如果参数为可变的呢?

>>> def change(n):n[0] = 'mr'
>>> name =  ['Mrs. Entity', 'Mrs. Thing']
>>> change(name)
>>> name
['mr', 'Mrs. Thing']

在前一个示例中,只是给局部变量赋了新值,而在这个示例中,修改了变量关联到的列表。这很奇怪吧?其实不那么奇怪。下面再这样做一次,但这次不使用函数调用。

>>> names = ['Mrs. Entity', 'Mrs. Thing']
>>> n = names # 再次假装传递名字作为参数
>>> n[0] = 'Mr. Gumby' # 修改列表
>>> names
['Mr. Gumby', 'Mrs. Thing']
将同一个列表赋给两个变量时,这两个变量将同时指向这个列表。要避免这样的结果,必须创建列表的副本。对序列执行切片操作时,返回的切片都是副本。因此,如果你创建覆盖整个列表的切片,得到的将是列表的副本。
>>> names = ['Mrs. Entity', 'Mrs. Thing']
>>> n = names[:]
# 现在n和names包含两个相等但不同的列表。
>>> n is names
False
>>> n == names
True
# 现在如果(像在函数change中那样)修改n,将不会影响names。
>>> n[0] = 'Mr. Gumby'
>>> n
['Mr. Gumby', 'Mrs. Thing']
>>> names
['Mrs. Entity', 'Mrs. Thing']
# 下面来尝试结合使用这种技巧和函数change。
>>> change(names[:])
>>> names
['Mrs. Entity', 'Mrs. Thing']
# 注意到参数n包含的是副本,因此原始列表是安全的。
  1. 为何修改参数

  2. 如果参数是不可更改的类型

    在这种情况下,应从函数返回所有需要的值(如果需要返回多个值,就以元组的方式返回它们)。

>>> def inc(x): return x + 1
...
>>> foo = 10
>>> foo = inc(foo)
>>> foo
11

如果一定要修改参数,可玩点花样,比如将值放在列表中,如下所示:

>>> def inc(x): x[0] = x[0] + 1
...
>>> foo = [10]
>>> inc(foo)
>>> foo
[11] 

但更清晰的解决方案是返回修改后的值。

6.4.3 关键字参数和默认值

请看下面两个函数:

def hello_1(greeting, name): print('{}, {}!'.format(greeting, name))
def hello_2(name, greeting): print('{}, {}!'.format(name, greeting))

这两个函数的功能完全相同,只是参数的排列顺序相反。

>>> hello_1('Hello', 'world')
Hello, world!
>>> hello_2('Hello', 'world')
Hello, world! 

有时候,参数的排列顺序可能难以记住,尤其是参数很多时。为了简化调用工作,可指定参数的名称。

>>> hello_1(greeting='Hello', name='world')
Hello, world!

在这里,参数的顺序无关紧要。

>>> hello_1(name='world', greeting='Hello')
Hello, world!

不过名称很重要。

>>> hello_2(greeting='Hello', name='world')
world, Hello! 

像这样使用名称指定的参数称为关键字参数,主要优点是有助于澄清各个参数的作用。
虽然这样做的输入量多些,但每个参数的作用清晰明了。另外,参数的顺序错了也没关系。然而,关键字参数最大的优点在于,可以指定默认值。

def hello_3(greeting='Hello', name='world'): print('{}, {}!'.format(greeting, name))

像这样给参数指定默认值后,调用函数时可不提供它!可以根据需要,一个参数值也不提供、提供部分参数值或提供全部参数值。

>>> hello_3()
Hello, world!
>>> hello_3('Greetings')
Greetings, world!
>>> hello_3('Greetings', 'universe')
Greetings, universe! 

如你所见,仅使用位置参数就很好,只不过如果要提供参数name,必须同时提供参数greeting。如果只想提供参数name,并让参数greeting使用默认值呢?相信你已猜到该怎么做了。

>>> hello_3(name='Gumby')
Hello, Gumby! 

很巧妙吧?还不止这些。你可结合使用位置参数和关键字参数,但必须先指定所有的位置参数,否则解释器将不知道它们是哪个参数(即不知道参数对应的位置)。


注意 通常不应结合使用位置参数和关键字参数,除非你知道这样做的后果。一般而言,除非必不可少的参数很少,而带默认值的可选参数很多,否则不应结合使用关键字参数和位置参数。


例如,函数hello可能要求必须指定姓名,而问候语和标点是可选的。

def hello_4(name, greeting='Hello', punctuation='!'): print('{}, {}{}'.format(greeting, name, punctuation))

调用这个函数的方式很多,下面是其中的一些:

>>> hello_4('Mars')
Hello, Mars!
>>> hello_4('Mars', 'Howdy')
Howdy, Mars!
>>> hello_4('Mars', 'Howdy', '...')
Howdy, Mars...
>>> hello_4('Mars', punctuation='.')
Hello, Mars.
>>> hello_4('Mars', greeting='Top of the morning to ya')
Top of the morning to ya, Mars!
>>> hello_4()
Traceback (most recent call last): File "<stdin>", line 1, in <module>
TypeError: hello_4() missing 1 required positional argument: 'name'

6.4.4 收集参数

有时候,允许用户提供任意数量的参数很有用。
请尝试使用下面这样的函数定义:

def print_params(*params): print(params)
>>> print_params('Testing')
('Testing',)

参数前面的星号将提供的所有值都放在一个元组中,也就是将这些值收集起来。这样的行为我们在5.2.1节见过:赋值时带星号的变量收集多余的值。它收集的是列表而不是元组中多余的值,但除此之外,这两种用法很像。下面再来编写一个函数:

def print_params_2(title, *params): print(title) print(params)
>>> print_params_2('Params:', 1, 2, 3)
Params:
(1, 2, 3)

因此星号意味着收集余下的位置参数。如果没有可供收集的参数,params将是一个空元组。

>>> print_params_2('Nothing:')
Nothing:
()

与赋值时一样,带星号的参数也可放在其他位置(而不是最后),但不同的是,在这种情况
下你需要做些额外的工作:使用名称来指定后续参数。

>>> def in_the_middle(x, *y, z):
...     print(x, y, z)
...
>>> in_the_middle(1, 2, 3, 4, 5, z=7)
1 (2, 3, 4, 5) 7
>>> in_the_middle(1, 2, 3, 4, 5, 7)
Traceback (most recent call last):  File "<stdin>", line 1, in <module>
TypeError: in_the_middle() missing 1 required keyword-only argument: 'z'

星号不会收集关键字参数。

>>> print_params_2('Hmm...', something=42)
Traceback (most recent call last):  File "<stdin>", line 1, in <module>
TypeError: print_params_2() got an unexpected keyword argument 'something'

要收集关键字参数,可使用两个星号。

>>> def print_params_3(**params):
...     print(params)
...
>>> print_params_3(x=1, y=2, z=3)
{'z': 3, 'x': 1, 'y': 2}

如你所见,这样得到的是一个字典而不是元组。可结合使用这些技术。

def print_params_4(x, y, z=3, *pospar, **keypar): print(x, y, z) print(pospar) print(keypar)

其效果与预期的相同。

>>> print_params_4(1, 2, 3, 5, 6, 7, foo=1, bar=2)
1 2 3
(5, 6, 7)
{'foo': 1, 'bar': 2}
>>> print_params_4(1, 2)
1 2 3
()
{}

通过结合使用这些技术,可做的事情很多。如果你想知道结合方式的工作原理(或是否可以
这样结合),动手试一试即可!在下一节你将看到,不管在函数定义中是否使用了*和**,都可在
函数调用中使用它们。
现在回到最初的问题:如何在姓名存储示例中使用这种技术?解决方案如下:

def store(data, *full_names): for full_name in full_names: names = full_name.split() if len(names) == 2: names.insert(1, '') labels = 'first', 'middle', 'last' for label, name in zip(labels, names): people = lookup(data, label, name) if people: people.append(full_name) else: data[label][name] = [full_name]

这个函数调用起来与只接受一个姓名的前一版一样容易。

>>> d = {}
>>> init(d)
>>> store(d, 'Han Solo')

但现在你也可以这样做:

>>> store(d, 'Luke Skywalker', 'Anakin Skywalker')
>>> lookup(d, 'last', 'Skywalker')
['Luke Skywalker', 'Anakin Skywalker']

6.4.5 分配参数

前面介绍了如何将参数收集到元组和字典中,但用同样的两个运算符(*和**)也可执行相
反的操作。与收集参数相反的操作是什么呢?假设有如下函数:

def add(x, y):  return x + y

注意 模块operator提供了这个函数的高效版本。

同时假设还有一个元组,其中包含两个你要相加的数。
params = (1, 2)
这与前面执行的操作差不多是相反的:不是收集参数,而是分配参数。这是通过在调用函数
(而不是定义函数)时使用运算符*实现的。

>>> add(*params)
3

这种做法也可用于参数列表的一部分,条件是这部分位于参数列表末尾。通过使用运算符**
可将字典中的值分配给关键字参数。如果你像前面那样定义了函数hello_3,就可像下面这样做:

>>> params = {'name': 'Sir Robin', 'greeting': 'Well met'}
>>> hello_3(**params)
Well met, Sir Robin!

如果在定义和调用函数时都使用***,将只传递元组或字典。因此还不如不使用它们,还
可省却些麻烦。

>>> def with_stars(**kwds):
...   print(kwds['name'], 'is', kwds['age'], 'years old')
...
>>> def without_stars(kwds):
...   print(kwds['name'], 'is', kwds['age'], 'years old')
...
>>> args = {'name': 'Mr. Gumby', 'age': 42}
>>> with_stars(**args)
Mr. Gumby is 42 years old
>>> without_stars(args)
Mr. Gumby is 42 years old

如你所见,对于函数with_stars,我在定义和调用它时都使用了星号,而对于函数without_
stars,我在定义和调用它时都没有使用,但这两种做法的效果相同。因此,只有在定义函数(允
许可变数量的参数)或调用函数时(拆分字典或序列)使用,星号才能发挥作用。
提示 使用这些拆分运算符来传递参数很有用,因为这样无需操心参数个数之类的问题,如下
所示:

def foo(x, y, z, m=0, n=0): print(x, y, z, m, n)
def call_foo(*args, **kwds): print("Calling foo!") foo(*args, **kwds)

这在调用超类的构造函数时特别有用(有关这方面的详细信息,请参阅第9章)。

6.4.6 练习使用参数

面对如此之多的参数提供和接受方式,很容易犯晕。下面来看一个综合示例。首先来定义一些函数。

def story(**kwds):return 'Once upon a time, there was a ' \'{job} called {name}.'.format_map(kwds)def power(x, y, *others):if others:print('Received redundant parameters:', others)return pow(x, y)def interval(start, stop=None, step=1):'Imitates range() for step > 0'if stop is None: # 如果没有给参数stop指定值start, stop = 0, start # 就调整参数start和stop的值result = []i = start # 从start开始往上数while i < stop: # 数到stop位置result.append(i) # 将当前数的数附加到result末尾i += step # 增加到当前数和step(> 0)之和return result

下面来尝试调用这些函数。

>>> print(story(job='king', name='Gumby'))
Once upon a time, there was a king called Gumby.
>>> print(story( name='Gumby', job='king'))
Once upon a time, there was a king called Gumby.
>>> params={'job':'language', 'name': 'python'}
>>> print(story(**params))
Once upon a time, there was a language called python.
>>> del params['job']
>>> print(story(job='stroke of genius', **params))
Once upon a time, there was a stroke of genius called python.
>>> power(2,3)
8
>>> power(3,2)
9
>>> power(y=3, x=2)
8
>>> params=(5,) * 2
>>> params
(5, 5)
>>> power(*params)
3125
>>> power(3,3,'Hello, world')
Received redundant parameters: ('Hello, world',)
27
>>> interval(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> interval(1,5)
[1, 2, 3, 4]
>>> interval(3,12,4)
[3, 7, 11]
>>> power(*interval(3,7))
Received redundant parameters: (5, 6)
81

请大胆尝试使用这些函数,直到你觉得自己掌握了所有相关的工作原理。

6.5 作用域

变量可视为指向值的名称,这与字典几乎是一样的(字典中的键指向值),变量可看作是“看不见”的字典。名为vars的内置函数,它返回这个不可见的字典:

>>> x=1
>>> scope=vars()
>>> scope['x']
1
>>> y=2
>>> scope=vars()
>>> scope['y']
2
>>> scope['x']
1

这个“看不见的字典”称为命名空间或作用域。那么有多少个命名空间呢?除全局作用域外,每个函数调用都创建一个命名空间。

>>> def foo(): x=42>>> x=1
>>> foo()
>>> x
1

函数foo修改了变量x,但x的值仍然为1,这是因为调用foo时创建了一个新的命名空间,供foo中的代码块使用。赋值语句x = 42是在这个内部作用域(局部命名空间)中执行的,不影响外部(全局)作用域内的x。在函数内使用的变量称为局部变量(与之相对的是全局变量)。参数类似于局部变量,因此参数与全局变量同名不会有任何问题。
但如果要在函数中访问全局变量呢?如果只是想读取这种变量的值(不重新关联它),通常不会有任何问题。

>>> def combine(parameter): print(parameter + external)
>>> external = 'berry'
>>> combine('Shrub')
Shrubberry

“遮盖”的问题
读取全局变量的值通常不会有问题,但还是存在出现问题的可能性。如果有一个局部变量或参数与你要访问的全局变量同名,就无法直接访问全局变量,因为它被局部变量遮住了。
如果需要,可使用函数globals来访问全局变量。这个函数类似于vars,返回一个包含全局变量的字典。(locals返回一个包含局部变量的字典。)
例如,在前面的示例中,如果有一个名为parameter的全局变量,就无法在函数combine中访问它,因为有一个与之同名的参数。然而,必要时可使用globals()[‘parameter’]来访问它。


>>> def combine(parameter): print(parameter + globals()['parameter'])
>>> parameter = 'berry'
>>> combine('Shrub')
Shrubberry

在函数内部给变量赋值时,该变量默认为局部变量,除非你明确地告诉Python它是全局变量。那么如何将这一点告知Python呢?使用global可以实现。

>>> x = 1
>>> def change_global(): global x x = x + 1
>>> change_global()
>>> x
2

作用域嵌套
Python函数可以嵌套,即可将一个函数放在另一个函数内,如下所示:

def foo(): def bar(): print("Hello, world!") bar()

嵌套通常用处不大,但有一个很突出的用途:使用一个函数来创建另一个函数。这意味着可像下面这样编写函数:

def multiplier(factor): def multiplyByFactor(number): return number * factor return multiplyByFactor

在这里,一个函数位于另一个函数中,且外面的函数返回里面的函数。也就是返回一个函数,而不是调用它。重要的是,返回的函数能够访问其定义所在的作用域。换而言之,它携带着自己所在的环境(和相关的局部变量)!
每当外部函数被调用时,都将重新定义内部的函数,而变量factor的值也可能不同。由于Python的嵌套作用域,可在内部函数中访问这个来自外部局部作用域(multiplier)的变量,如下所示:

>>> double = multiplier(2)
>>> double(5)
10
>>> triple = multiplier(3)
>>> triple(3)
9
>>> multiplier(5)(4)
20

像multiplyByFactor这样存储其所在作用域的函数称为闭包
通常,不能给外部作用域内的变量赋值,但如果一定要这样做,可使用关键字nonlocal。这个关键字的用法与global很像,让你能够给外部作用域(非全局作用域)内的变量赋值。


6.6 递归

下面是一个递归式函数定义:

def recursion(): return recursion()

这个定义显然什么都没有做。如果你运行它,结果将如何呢?你将发现运行一段时间后,这个程序崩溃了(引发异常)。从理论上说,这个程序将不断运行下去,但每次调用函数时,都将消耗一些内存。因此函数调用次数达到一定的程度(且之前的函数调用未返回)后,将耗尽所有的内存空间,导致程序终止并显示错误消息“超过最大递归深度”。
这个函数中的递归称为无穷递归(就像以while True打头且不包含break和return语句的循环被称为无限循环一样),因为它从理论上说永远不会结束。你想要的是能对你有所帮助的递归函数,这样的递归函数通常包含下面两部分。
 基线条件(针对最小的问题):满足这种条件时函数将直接返回一个值。
 递归条件:包含一个或多个调用,这些调用旨在解决问题的一部分。
这里的关键是,通过将问题分解为较小的部分,可避免递归没完没了,因为问题终将被分解成基线条件可以解决的最小问题。
那么如何让函数调用自身呢?这没有看起来那么难懂。前面说过,每次调用函数时,都将为此创建一个新的命名空间。这意味着函数调用自身时,是两个不同的函数[更准确地说,是不同版本(即命名空间不同)的同一个函数]在交流。

6.6.1 两个经典案例:阶乘和幂

def factorial(n):if n==1:return 1else:return n*factorial(n-1)
def power(x, n):if n == 0:return 1else:return x * power(x, n-1)

6.6.2 二分法查找

例如,对方心里想着一个1~100的数字,你必须猜出是哪个。当然,猜100次肯定猜对,但最少需要猜多少次呢?
实际上只需猜7次。首先问:“这个数字大于50吗?”如果答案是肯定的,再问:“这个数字大于75吗?”不断将可能的区间减半,直到猜对为止。你无需过多地思考就能成功。

def search(sequence, number, lower=0, upper=None):if upper is None: upper=len(sequence) -1if lower ==upper:assert number == sequence[upper]return upperelse:middle = (lower + upper) // 2if number > sequence[middle]:return search(sequence, number, middle+1, upper)else:return search(sequence, number,lower, middle)

一些补充

1、元组类型变长参数传递

使用可变长参数可让Python 的函数处理比初始化声明时更多的参数。在函数声明时,若在某个参数名称前面加一个星号:* ,则表示该参数是一个元组类型可变长参数。在调用该函数的时,依次将必须赋值完毕后,将继续依次从调用时所提供的参数元组中接收元素值为可变长参数赋值。如果在函数调用时没有提供元组类型参数,相当于提供了一个空元组,即不必传递可变长参数。例如:

def printse_series(d,*dtup):print('必须参数:',d)if len(dtup) != 0:print('元组参数:',end = '')for i in dtup:print(i,end=' ')print(printse_series(10))
print(printse_series(10,20,30,40,50))
运行结果为:
必须参数: 10
None
必须参数: 10
元组参数:20 30 40 50 None

2、字典类型变长参数传递

在函数声明时,若在其某个参数名称前加两个星号:** ,则表示该参数是一个字典类型可变长参数。在调用该函数时,以实参变量名等于字典值的方式传递参数,由函数自动按字典值接收,实参变量名以字符形式作为字典的键。因此字典是无序的,因此字典的键值对也不分先后顺序。如果在函数调用时没有提供字典类型参数,则相当于提供了一个空子典,即不必传递可变长参数。

def printse_series(d,*dtup,**ddic):print('必须参数:',d)if len(dtup) != 0:print('元组:',end = '')for i in dtup:print(i,end=' ')if len(ddic) != 0:print('\n字典:',ddic)for k in ddic:print('%s 对应 %s' % (k,ddic[k]))printse_series(1,2,3,4,5,6,x=10,y=20,z=30)
运行的结果:
必须参数: 1
元组:2 3 4 5 6
字典: {'x': 10, 'y': 20, 'z': 30}
x 对应 10
y 对应 20
z 对应 30

3、高阶函数
Python是面向对象的程序,对象名可以指向函数。高阶函数就是能够接受将函数对象名称作为参数传入的函数。应该注意的是,这里对象名称的类型是函数而不是字符串。例如:

def add(x,y):return x+y
def subtract(x,y):return x-y
def myfunc(x,y,f):  # 形参 f 的类型为函数对象return f(x,y)
a,b = 5,2
method=add #注意 f 的类型为函数对象
print('%s: 参数1为 %d,参数2为 %d,结果为%d' % (method,a,b,myfunc(a,b,method)))
method=subtract #注意 f 的类型为函数对象
print('%s: 参数1为 %d,参数2为 %d,结果为%d' % (method,a,b,myfunc(a,b,method)))
运行的结果为:
<function add at 0x10253f1e0>: 参数1为 5,参数2为 2,结果为7
<function subtract at 0x102601268>: 参数1为 5,参数2为 2,结果为3

4、匿名函数

匿名函数: 就是没有实际名称的函数。Python 使用lambda来创建匿名函数。在lambda表达式中封装简单的逻辑,其主体仅是一个表达式而不需要使用代码。其通式:<函数对象名>= lambda <形式参数列表>:<表达式>,例如:

def add(x,y):return x+y上面可以定义为匿名函数:add1= lambda x,y: x+y上面的调用方式如下:a,b = 2.5,3.6
sum = add1(a,b)或者直接调用(lambda x,y:x+y)(2.5,3.6)其结果都是 6.1

匿名函数也可以嵌套条件分支,完成较为复杂的逻辑,例如返回x,y中较大的值

maxValue = lambda x,y: x if x>=y else y
print('maxValue =',maxValue(2,3))
结果为:
maxValue = 3

5、生成器函数

  • 生成器:是能够按照解析表达式逐次产生出数据项元素的函数。在Python语言中,利用生成器,可不必创建完整的数据集合,从而节省存储的空间。

    • 生成器函数与普通的函数的差别主要在于:生成器函数体中用 yield 关键字生成数据项,而不是用print输出数据项。生成器函数的调用循环遍历时,可以用 __next__() 方法获取 yield 生成数据项。

    • 生成器函数与普通函数的执行流程不同。普通的函数时顺序执行的,遇到 return 语句或 最后一条语句就返回。而生成器函数在每次调用__next__()方法的时候才执行,遇到yield语句返回,再次执行时不是从头开始,而是从上次返回的yield语句处继续执行。例如:用生成器产生连续偶数序列并输出三次测试的结果。

      def generatior_even():for i in range(1,11):print('第%d步'%i)yield i*2
      g = generatior_even()
      print(g.__next__())   # 此处连续执行三次,结果可见,并非每次从头开始
      print(g.__next__())   # 而是从上次执行yield 语句处继续执行
      print(g.__next__())
      

Python基础教程(第3版)》笔记:第6章抽象相关推荐

  1. python基础教程第4版-Python基础教程(第3版) 笔记(四)

    第二章 列表和元素 2.1 序列概述 列表和元组的主要不同在于,列表是可以修改的,而元组不可以. 创建一个由数据库中所有人员组成的列表: >>> edward = ['Edward ...

  2. python基础教程第三版试题-Python基础教程(第3版) 笔记(二)

    1.8模块 Python提供了完成(某人的年 龄为32.9,并想将这个值向下圆整为32,因为他还没有满33岁)这种任务的函 数floor. 导入模块,可以使用特殊命令import.函数floor包含在 ...

  3. Python基础教程(第3版) 笔记(一)

    1.1 数和表达式: 除法运算的结果为小数,即浮点数 >>>1/2 0.5 除法运算为整数,使用双斜杠 >>>1//2 0 >>>5.0//2.4 ...

  4. python的符号lt和gt怎么输入_lt;lt;Python基础教程gt;gt;学习笔记 | 第12章 | 图形用户界面...

    Python支持的工具包非常多.但没有一个被觉得标准的工具包.用户选择的自由度大些.本章主要介绍最成熟的跨平台工具包wxPython.官方文档: ------ 丰富的平台: Tkinter实际上类似于 ...

  5. python基础教程电子版-Python基础教程(第2版 修订版) pdf

    Python基础教程(第2版 修订版) 目录 D11章快速改造:基础知识1 1.1安装Python1 1.1.1Windows1 1.1.2Linux和UNIX3 1.1.3苹果机(Macintosh ...

  6. Python基础教程(第2版 修订版) pdf

    Python基础教程(第2版 修订版) 目录 D11章快速改造:基础知识1 1.1安装Python1 1.1.1Windows1 1.1.2Linux和UNIX3 1.1.3苹果机(Macintosh ...

  7. 《python基础教程(第二版)》学习笔记 基础部分(第1章)

    <python基础教程(第二版)>学习笔记 基础部分(第1章) python常用的IDE: Windows: IDLE(gui), Eclipse+PyDev; Python(comman ...

  8. 《Python基础教程(第3版)》笔记:第8章异常

    <Python基础教程(第3版)>笔记:异常 重点 第8章 异常 异常对象未被处理(或捕获)时,程序将终止并显示一条错误信息:traceback 每个异常都是某个类的实例, 如何创建异常 ...

  9. Python 基础教程(第二版)读书笔记

    Python 基础教程(第二版) 第一章 在 Python 3 中可直接使用长整数,而不必添加 L 或者 l 的后缀. print在 Python 3 中是函数. 在交互式解释器中使用 if 语句,需 ...

最新文章

  1. 深入掌握JMS(一):JMS基础
  2. leetcode 最长公共前缀
  3. 【千字分析】剑指 Offer 46. 把数字翻译成字符串
  4. 14行代码AC——1017 A除以B (20分)(大数运算+讲解)
  5. Xamarin效果第十二篇之控制祖传PLC
  6. SpringMvc @RequestParam、 @RequestBody、@RequestPart 的区别
  7. LeetCode 1790. 仅执行一次字符串交换能否使两个字符串相等
  8. linux 启动,停止mysql
  9. 设置python的中文字体显示
  10. QT每日一练day5:QLabel和按钮窗口打印功能
  11. python下载的库包放_python下载的库包存放路径
  12. 外螺纹对照表_美制螺纹内外径对照表unf
  13. 基于ueditor 扩展的电子病历编辑器
  14. 【imx6ul】从头搭建imx6ul开发环境(uboot、内核编译及烧入、mfgtools详细使用方法)
  15. 解决mac休眠睡眠异常耗电方法
  16. CSS 排版与正常流 —— 重学CSS
  17. Oracle 裁减了Java布道师员工
  18. 阿里云盘映射webdav操作
  19. c语言程序设计书店销售管理系统,C语言课程设计-书店管理系统
  20. directshow(directShow多个usb摄像头方案)

热门文章

  1. お兄ちゃんといっしょ♪ 与哥哥在一起 汉化补丁
  2. JAVA servlet doFilter()用法
  3. 让中药的12位美白仙子重塑健康肌肤
  4. 基于51单片机超声波智能测距仪设计(毕设课设)
  5. HTML常见字体符号
  6. JVM##入门到深入--快速上手
  7. Python字符串与时间相互转换
  8. 苹果前置摄像头拍出来是反的怎么调_苹果前置拍照怎么反的。怎么调正
  9. CLOCK_DEDICATED_ROUTE约束应用
  10. mosquitto客户端对象“struct mosquitto *mosq”管理下篇(mosquitto2.0.15客户端源码分析之四)