python3函数性能,python三个特性-成都创新互联网站建设

关于创新互联

多方位宣传企业产品与服务 突出企业形象

公司简介 公司的服务 荣誉资质 新闻动态 联系我们

python3函数性能,python三个特性

「Python3基础」函数

表示一个功能,函数定义着是提供功能的人,函数调用者是使用功能的人。

创新互联建站主营张家港网站建设的网络公司,主营网站建设方案,重庆APP开发,张家港h5成都微信小程序搭建,张家港网站营销推广欢迎张家港等地区企业咨询

print:打印功能,将括号中的内容,显示到终端。

将括号中的内容显示在控制台.

input:输入功能,从终端中获取输入的信息,存到程序变量当中

作用:将用户输入的内容赋值给变量

第一个字符必须是字母表中字母或下划线 _ 。

标识符的其他的部分由字母、数字和下划线组成。

标识符对大小写敏感。

python最具特色的就是使用缩进来表示代码块,不需要使用大括号 {} 。

缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数。实例如下:

后端编程Python3-调试、测试和性能剖析(下)

单元测试(Unit Testing)

为程序编写测试——如果做的到位——有助于减少bug的出现,并可以提高我们对程序按预期目标运行的信心。通常,测试并不能保证正确性,因为对大多数程序而言, 可能的输入范围以及可能的计算范围是如此之大,只有其中最小的一部分能被实际地进 行测试。尽管如此,通过仔细地选择测试的方法和目标,可以提高代码的质量。

大量不同类型的测试都可以进行,比如可用性测试、功能测试以及整合测试等。这里, 我们只讲单元测试一对单独的函数、类与方法进行测试,确保其符合预期的行为。

TDD的一个关键点是,当我们想添加一个功能时——比如为类添加一个方法—— 我们首次为其编写一个测试用例。当然,测试将失败,因为我们还没有实际编写该方法。现在,我们编写该方法,一旦方法通过了测试,就可以返回所有测试,确保我们新添加的代码没有任何预期外的副作用。一旦所有测试运行完毕(包括我们为新功能编写的测试),就可以对我们的代码进行检查,并有理有据地相信程序行为符合我们的期望——当然,前提是我们的测试是适当的。

比如,我们编写了一个函数,该函数在特定的索引位置插入一个字符串,可以像下面这样开始我们的TDD:

def insert_at(string, position, insert):

"""Returns a copy of string with insert inserted at the position

string = "ABCDE"

result =[]

for i in range(-2, len(string) + 2):

... result.append(insert_at(string, i,“-”))

result[:5]

['ABC-DE', 'ABCD-E', '-ABCDE','A-BCDE', 'AB-CDE']

result[5:]

['ABC-DE', 'ABCD-E', 'ABCDE-', 'ABCDE-']

"""

return string

对不返回任何参数的函数或方法(通常返回None),我们通常赋予其由pass构成的一个suite,对那些返回值被试用的,我们或者返回一个常数(比如0),或者某个不变的参数——这也是我们这里所做的。(在更复杂的情况下,返回fake对象可能更有用一一对这样的类,提供mock对象的第三方模块是可用的。)

运行doctest时会失败,并列出每个预期内的字符串('ABCD-EF'、'ABCDE-F' 等),及其实际获取的字符串(所有的都是'ABCD-EF')。一旦确定doctest是充分的和正确的,就可以编写该函数的主体部分,在本例中只是简单的return string[:position] + insert+string[position:]。(如果我们编写的是 return string[:position] + insert,之后复制 string [:position]并将其粘贴在末尾以便减少一些输入操作,那么doctest会立即提示错误。)

Python的标准库提供了两个单元测试模块,一个是doctest,这里和前面都简单地提到过,另一个是unittest。此外,还有一些可用于Python的第三方测试工具。其中最著名的两个是nose (code.google.com/p/python-nose)与py.test (codespeak.net/py/dist/test/test.html), nose 致力于提供比标准的unittest 模块更广泛的功能,同时保持与该模块的兼容性,py.test则采用了与unittest有些不同的方法,试图尽可能消除样板测试代码。这两个第三方模块都支持测试发现,因此没必要写一个总体的测试程序——因为模块将自己搜索测试程序。这使得测试整个代码树或某一部分 (比如那些已经起作用的模块)变得很容易。那些对测试严重关切的人,在决定使用哪个测试工具之前,对这两个(以及任何其他有吸引力的)第三方模块进行研究都是值 得的。

创建doctest是直截了当的:我们在模块中编写测试、函数、类与方法的docstrings。 对于模块,我们简单地在末尾添加了 3行:

if __name__ =="__main__":

import doctest

doctest.testmod()

在程序内部使用doctest也是可能的。比如,blocks.py程序(其模块在后面)有自己函数的doctest,但以如下代码结尾:

if __name__== "__main__":

main()

这里简单地调用了程序的main()函数,并且没有执行程序的doctest。要实验程序的 doctest,有两种方法。一种是导入doctest模块,之后运行程序---比如,在控制台中输 入 python3 -m doctest blocks.py (在 Wndows 平台上,使用类似于 C:Python3 lpython.exe 这样的形式替代python3)。如果所有测试运行良好,就没有输出,因此,我们可能宁愿执行python3-m doctest blocks.py-v,因为这会列出每个执行的doctest,并在最后给出结果摘要。

另一种执行doctest的方法是使用unittest模块创建单独的测试程序。在概念上, unittest模块是根据Java的JUnit单元测试库进行建模的,并用于创建包含测试用例的测试套件。unittest模块可以基于doctests创建测试用例,而不需要知道程序或模块包含的任何事物——只要知道其包含doctest即可。因此,为给blocks.py程序制作一个测试套件,我们可以创建如下的简单程序(将其称为test_blocks.py):

import doctest

import unittest

import blocks

suite = unittest.TestSuite()

suite.addTest(doctest.DocTestSuite(blocks))

runner = unittest.TextTestRunner()

print(runner.run(suite))

注意,如果釆用这种方法,程序的名称上会有一个隐含的约束:程序名必须是有效的模块名。因此,名为convert-incidents.py的程序的测试不能写成这样。因为import convert-incidents不是有效的,在Python标识符中,连接符是无效的(避开这一约束是可能的,但最简单的解决方案是使用总是有效模块名的程序文件名,比如,使用下划线替换连接符)。这里展示的结构(创建一个测试套件,添加一个或多个测试用例或测试套件,运行总体的测试套件,输出结果)是典型的机遇unittest的测试。运行时,这一特定实例产生如下结果:

...

.............................................................................................................

Ran 3 tests in 0.244s

OK

每次执行一个测试用例时,都会输出一个句点(因此上面的输出最前面有3个句点),之后是一行连接符,再之后是测试摘要(如果有任何一个测试失败,就会有更多的输出信息)。

如果我们尝试将测试分离开(典型情况下是要测试的每个程序和模块都有一个测试用例),就不要再使用doctests,而是直接使用unittest模块的功能——尤其是我们习惯于使用JUnit方法进行测试时ounittest模块会将测试分离于代码——对大型项目(测试编写人员与开发人员可能不一致)而言,这种方法特别有用。此外,unittest单元测试编写为独立的Python模块,因此,不会像在docstring内部编写测试用例时受到兼容性和明智性的限制。

unittest模块定义了 4个关键概念。测试夹具是一个用于描述创建测试(以及用完之后将其清理)所必需的代码的术语,典型实例是创建测试所用的一个输入文件,最后删除输入文件与结果输出文件。测试套件是一组测试用例的组合。测试用例是测试的基本单元—我们很快就会看到实例。测试运行者是执行一个或多个测试套件的对象。

典型情况下,测试套件是通过创建unittest.TestCase的子类实现的,其中每个名称 以“test”开头的方法都是一个测试用例。如果我们需要完成任何创建操作,就可以在一个名为setUp()的方法中实现;类似地,对任何清理操作,也可以实现一个名为 tearDown()的方法。在测试内部,有大量可供我们使用的unittest.TestCase方法,包括 assertTrue()、assertEqual()、assertAlmostEqual()(对于测试浮点数很有用)、assertRaises() 以及更多,还包括很多对应的逆方法,比如assertFalse()、assertNotEqual()、failIfEqual()、 failUnlessEqual ()等。

unittest模块进行了很好的归档,并且提供了大量功能,但在这里我们只是通过一 个非常简单的测试套件来感受一下该模块的使用。这里将要使用的实例,该练习要求创建一个Atomic模块,该模块可以用作一 个上下文管理器,以确保或者所有改变都应用于某个列表、集合或字典,或者所有改变都不应用。作为解决方案提供的Atomic.py模块使用30行代码来实现Atomic类, 并提供了 100行左右的模块doctest。这里,我们将创建test_Atomic.py模块,并使用 unittest测试替换doctest,以便可以删除doctest。

在编写测试模块之前,我们需要思考都需要哪些测试。我们需要测试3种不同的数据类型:列表、集合与字典。对于列表,需要测试的是插入项、删除项或修改项的值。对于集合,我们必须测试向其中添加或删除一个项。对于字典,我们必须测试的是插入一个项、修改一个项的值、删除一个项。此外,还必须要测试的是在失败的情况下,不会有任何改变实际生效。

结构上看,测试不同数据类型实质上是一样的,因此,我们将只为测试列表编写测试用例,而将其他的留作练习。test_Atomic.py模块必须导入unittest模块与要进行测试的Atomic模块。

创建unittest文件时,我们通常创建的是模块而非程序。在每个模块内部,我们定义一个或多个unittest.TestCase子类。比如,test_Atomic.py模块中仅一个单独的 unittest-TestCase子类,也就是TestAtomic (稍后将对其进行讲解),并以如下两行结束:

if name == "__main__":

unittest.main()

这两行使得该模块可以单独运行。当然,该模块也可以被导入并从其他测试程序中运行——如果这只是多个测试套件中的一个,这一点是有意义的。

如果想要从其他测试程序中运行test_Atomic.py模块,那么可以编写一个与此类似的程序。我们习惯于使用unittest模块执行doctests,比如:

import unittest

import test_Atomic

suite = unittest.TestLoader().loadTestsFromTestCase(test_Atomic.TestAtomic)

runner = unittest.TextTestRunner()

pnnt(runner.run(suite))

这里,我们已经创建了一个单独的套件,这是通过让unittest模块读取test_Atomic 模块实现的,并且使用其每一个test*()方法(本实例中是test_list_success()、test_list_fail(),稍后很快就会看到)作为测试用例。

我们现在将查看TestAtomic类的实现。对通常的子类(不包括unittest.TestCase 子类),不怎么常见的是,没有必要实现初始化程序。在这一案例中,我们将需要建立 一个方法,但不需要清理方法,并且我们将实现两个测试用例。

def setUp(self):

self.original_list = list(range(10))

我们已经使用了 unittest.TestCase.setUp()方法来创建单独的测试数据片段。

def test_list_succeed(self):

items = self.original_list[:]

with Atomic.Atomic(items) as atomic:

atomic.append(1999)

atomic.insert(2, -915)

del atomic[5]

atomic[4]= -782

atomic.insert(0, -9)

self.assertEqual(items,

[-9, 0, 1, -915, 2, -782, 5, 6, 7, 8, 9, 1999])

def test_list_fail(self):

items = self.original_list[:]

with self.assertRaises(AttributeError):

with Atomic.Atomic(items) as atomic:

atomic.append(1999)

atomic.insert(2, -915)

del atomic[5]

atomic[4] = -782

atomic.poop() # Typo

self.assertListEqual(items, self.original_list)

这里,我们直接在测试方法中编写了测试代码,而不需要一个内部函数,也不再使用unittest.TestCase.assertRaised()作为上下文管理器(期望代码产生AttributeError)。 最后我们也使用了 Python 3.1 的 unittest.TestCase.assertListEqual()方法。

正如我们已经看到的,Python的测试模块易于使用,并且极为有用,在我们使用 TDD的情况下更是如此。它们还有比这里展示的要多得多的大量功能与特征——比如,跳过测试的能力,这有助于理解平台差别——并且这些都有很好的文档支持。缺失的一个功能——但nose与py.test提供了——是测试发现,尽管这一特征被期望在后续的Python版本(或许与Python 3.2—起)中出现。

性能剖析(Profiling)

如果程序运行很慢,或者消耗了比预期内要多得多的内存,那么问题通常是选择的算法或数据结构不合适,或者是以低效的方式进行实现。不管问题的原因是什么, 最好的方法都是准确地找到问题发生的地方,而不只是检査代码并试图对其进行优化。 随机优化会导致引入bug,或者对程序中本来对程序整体性能并没有实际影响的部分进行提速,而这并非解释器耗费大部分时间的地方。

在深入讨论profiling之前,注意一些易于学习和使用的Python程序设计习惯是有意义的,并且对提高程序性能不无裨益。这些技术都不是特定于某个Python版本的, 而是合理的Python程序设计风格。第一,在需要只读序列时,最好使用元组而非列表; 第二,使用生成器,而不是创建大的元组和列表并在其上进行迭代处理;第三,尽量使用Python内置的数据结构 dicts、lists、tuples 而不实现自己的自定义结构,因为内置的数据结构都是经过了高度优化的;第四,从小字符串中产生大字符串时, 不要对小字符串进行连接,而是在列表中累积,最后将字符串列表结合成为一个单独的字符串;第五,也是最后一点,如果某个对象(包括函数或方法)需要多次使用属性进行访问(比如访问模块中的某个函数),或从某个数据结构中进行访问,那么较好的做法是创建并使用一个局部变量来访问该对象,以便提供更快的访问速度。

Python标准库提供了两个特别有用的模块,可以辅助调査代码的性能问题。一个是timeit模块——该模块可用于对一小段Python代码进行计时,并可用于诸如对两个或多个特定函数或方法的性能进行比较等场合。另一个是cProfile模块,可用于profile 程序的性能——该模块对调用计数与次数进行了详细分解,以便发现性能瓶颈所在。

为了解timeit模块,我们将查看一些小实例。假定有3个函数function_a()、 function_b()、function_c(), 3个函数执行同样的计算,但分别使用不同的算法。如果将这些函数放于同一个模块中(或分别导入),就可以使用timeit模块对其进行运行和比较。下面给出的是模块最后使用的代码:

if __name__ == "__main__":

repeats = 1000

for function in ("function_a", "function_b", "function_c"):

t = timeit.Timer("{0}(X, Y)".format(function),"from __main__ import {0}, X, Y".format(function))

sec = t.timeit(repeats) / repeats

print("{function}() {sec:.6f} sec".format(**locals()))

赋予timeit.Timer()构造子的第一个参数是我们想要执行并计时的代码,其形式是字符串。这里,该字符串是“function_a(X,Y)”;第二个参数是可选的,还是一个待执行的字符串,这一次是在待计时的代码之前,以便提供一些建立工作。这里,我们从 __main__ (即this)模块导入了待测试的函数,还有两个作为输入数据传入的变量(X 与Y),这两个变量在该模块中是作为全局变量提供的。我们也可以很轻易地像从其他模块中导入数据一样来进行导入操作。

调用timeit.Timer对象的timeit()方法时,首先将执行构造子的第二个参数(如果有), 之后执行构造子的第一个参数并对其执行时间进行计时。timeit.Timer.timeit()方法的返回值是以秒计数的时间,类型是float。默认情况下,timeit()方法重复100万次,并返回所 有这些执行的总秒数,但在这一特定案例中,只需要1000次反复就可以给出有用的结果, 因此对重复计数次数进行了显式指定。在对每个函数进行计时后,使用重复次数对总数进行除法操作,就得到了平均执行时间,并在控制台中打印出函数名与执行时间。

function_a() 0.001618 sec

function_b() 0.012786 sec

function_c() 0.003248 sec

在这一实例中,function_a()显然是最快的——至少对于这里使用的输入数据而言。 在有些情况下一一比如输入数据不同会对性能产生巨大影响——可能需要使用多组输入数据对每个函数进行测试,以便覆盖有代表性的测试用例,并对总执行时间或平均执行时间进行比较。

有时监控自己的代码进行计时并不是很方便,因此timeit模块提供了一种在命令行中对代码执行时间进行计时的途径。比如,要对MyModule.py模块中的函数function_a()进行计时,可以在控制台中输入如下命令:python3 -m timeit -n 1000 -s "from MyModule import function_a, X, Y" "function_a(X, Y)"(与通常所做的一样,对 Windows 环境,我们必须使用类似于C:Python3lpython.exe这样的内容来替换python3)。-m选项用于Python 解释器,使其可以加载指定的模块(这里是timeit),其他选项则由timeit模块进行处理。 -n选项指定了循环计数次数,-s选项指定了要建立,最后一个参数是要执行和计时的代码。命令完成后,会向控制台中打印运行结果,比如:

1000 loops, best of 3: 1.41 msec per loop

之后我们可以轻易地对其他两个函数进行计时,以便对其进行整体的比较。

cProfile模块(或者profile模块,这里统称为cProfile模块)也可以用于比较函数 与方法的性能。与只是提供原始计时的timeit模块不同的是,cProfile模块精确地展示 了有什么被调用以及每个调用耗费了多少时间。下面是用于比较与前面一样的3个函数的代码:

if __name__ == "__main__":

for function in ("function_a", "function_b", "function_c"):

cProfile.run("for i in ranged 1000): {0}(X, Y)".format(function))

我们必须将重复的次数放置在要传递给cProfile.run()函数的代码内部,但不需要做任何创建,因为模块函数会使用内省来寻找需要使用的函数与变量。这里没有使用显式的print()语句,因为默认情况下,cProfile.run()函数会在控制台中打印其输出。下面给出的是所有函数的相关结果(有些无关行被省略,格式也进行了稍许调整,以便与页面适应):

1003 function calls in 1.661 CPU seconds

ncalls tottime percall cumtime percall filename:lineno(function)

1 0.003 0.003 1.661 1.661 :1 ( )

1000 1.658 0.002 1.658 0.002 MyModule.py:21 (function_a)

1 0.000 0.000 1.661 1.661 {built-in method exec}

5132003 function calls in 22.700 CPU seconds

ncalls tottime percall cumtime percall filename:lineno(function)

1 0.487 0.487 22.700 22.700 : 1 ( )

1000 0.011 0.000 22.213 0.022 MyModule.py:28(function_b)

5128000 7.048 0.000 7.048 0.000 MyModule.py:29( )

1000 0.00 50.000 0.005 0.000 {built-in method bisectjeft}

1 0.000 0.000 22.700 22.700 {built-in method exec}

1000 0.001 0.000 0.001 0.000 {built-in method len}

1000 15.149 0.015 22.196 0.022 {built-in method sorted}

5129003 function calls in 12.987 CPU seconds

ncalls tottime percall cumtime percall filename:lineno(function)

1 0.205 0.205 12.987 12.987 :l ( )

1000 6.472 0.006 12.782 0.013 MyModule.py:36(function_c)

5128000 6.311 0.000 6.311 0.000 MyModule.py:37( )

1 0.000 0.000 12.987 12.987 {built-in method exec}

ncalls ("调用的次数")列列出了对指定函数(在filename:lineno(function)中列出) 的调用次数。回想一下我们重复了 1000次调用,因此必须将这个次数记住。tottime (“总的时间”)列列出了某个函数中耗费的总时间,但是排除了函数调用的其他函数内部花费的时间。第一个percall列列出了对函数的每次调用的平均时间(tottime // ncalls)。 cumtime ("累积时间")列出了在函数中耗费的时间,并且包含了函数调用的其他函数内部花费的时间。第二个percall列列出了对函数的每次调用的平均时间,包括其调用的函数耗费的时间。

这种输出信息要比timeit模块的原始计时信息富有启发意义的多。我们立即可以发现,function_b()与function_c()使用了被调用5000次以上的生成器,使得它们的速度至少要比function_a()慢10倍以上。并且,function_b()调用了更多通常意义上的函数,包括调用内置的sorted()函数,这使得其几乎比function_c()还要慢两倍。当然,timeit() 模块提供了足够的信息来查看计时上存在的这些差别,但cProfile模块允许我们了解为什么会存在这些差别。正如timeit模块允许对代码进行计时而又不需要对其监控一样,cProfile模块也可以做到这一点。然而,从命令行使用cProfile模块时,我们不能精确地指定要执行的 是什么——而只是执行给定的程序或模块,并报告所有这些的计时结果。需要使用的 命令行是python3 -m cProfile programOrModule.py,产生的输出信息与前面看到的一 样,下面给出的是输出信息样例,格式上进行了一些调整,并忽略了大多数行:

10272458 function calls (10272457 primitive calls) in 37.718 CPU secs

ncalls tottime percall cumtime percall filename:lineno(function)

10.000 0.000 37.718 37.718 :1 ( )

10.719 0.719 37.717 37.717 :12( )

1000 1.569 0.002 1.569 0.002 :20(function_a)

1000 0.011 0.000 22.560 0.023 :27(function_b)

5128000 7.078 0.000 7.078 0.000 :28( )

1000 6.510 0.007 12.825 0.013 :35(function_c)

5128000 6.316 0.000 6.316 0.000 :36( )

在cProfile术语学中,原始调用指的就是非递归的函数调用。

以这种方式使用cProfile模块对于识别值得进一步研究的区域是有用的。比如,这里 我们可以清晰地看到function_b()需要耗费更长的时间,但是我们怎样获取进一步的详细资料?我们可以使用cProfile.run("function_b()")来替换对function_b()的调用。或者可以保存完全的profile数据并使用pstats模块对其进行分析。要保存profile,就必须对命令行进行稍许修改:python3 -m cProfile -o profileDataFile programOrModule.py。 之后可以对 profile 数据进行分析,比如启动IDLE,导入pstats模块,赋予其已保存的profileDataFile,或者也可以在控制台中交互式地使用pstats。

下面给出的是一个非常短的控制台会话实例,为使其适合页面展示,进行了适当调整,我们自己的输入则以粗体展示:

$ python3 -m cProfile -o profile.dat MyModule.py

$ python3 -m pstats

Welcome to the profile statistics browser.

% read profile.dat

profile.dat% callers function_b

Random listing order was used

List reduced from 44 to 1 due to restriction

Function was called by...

ncalls tottime cumtime

:27(function_b) - 1000 0.011 22.251 :12( )

profile.dat% callees function_b

Random listing order was used

List reduced from 44 to 1 due to restriction

Function called...

ncalls tottime cumtime

:27(function_b)-

1000 0.005 0.005 built-in method bisectJeft

1000 0.001 0.001 built-in method len

1000 1 5.297 22.234 built-in method sorted

profile.dat% quit

输入help可以获取命令列表,help后面跟随命令名可以获取该命令的更多信息。比如, help stats将列出可以赋予stats命令的参数。还有其他一些可用的工具,可以提供profile数据的图形化展示形式,比如 RunSnakeRun (), 该工具需要依赖于wxPython GUI库。

使用timeit与cProfile模块,我们可以识别出我们自己代码中哪些区域会耗费超过预期的时间;使用cProfile模块,还可以准确算岀时间消耗在哪里。

以上内容部分摘自视频课程 05后端编程Python-19调试、测试和性能调优(下) ,更多实操示例请参照视频讲解。跟着张员外讲编程,学习更轻松,不花钱还能学习真本领。

python3和python2区别有什么

python2版本和python3版本的区别,两者对比如下

核心类差异

1. Python3 对 Unicode 字符的原生支持。

Python2 中使用 ASCII 码作为默认编码方式导致 string 有两种类型 str 和 unicode,Python3 只

支持 unicode 的 string。Python2 和 Python3 字节和字符对应关系为:

2. Python3 采用的是绝对路径的方式进行 import

Python2 中相对路径的 import 会导致标准库导入变得困难(想象一下,同一目录下有 file.py,如

何同时导入这个文件和标准库 file)。Python3 中这一点将被修改,如果还需要导入同一目录的文件必

须使用绝对路径,否则只能使用相关导入的方式来进行导入。

3. Python2 中存在老式类和新式类的区别,Python3 统一采用新式类。新式类声明要求继承 object,

必须用新式类应用多重继承。

4. Python3 使用更加严格的缩进。Python2 的缩进机制中,1 个 tab 和 8 个 space 是等价的,所

以在缩进中可以同时允许 tab 和 space 在代码中共存。这种等价机制会导致部分 IDE 使用存在问题。

Python3 中 1 个 tab 只能找另外一个 tab 替代,因此 tab 和 space 共存会导致报错:TabError:

inconsistent use of tabs and spaces in indentation.

python学习网,免费的python学习网站,欢迎在线学习!

废弃类差异

1. print 语句被 Python3 废弃,统一使用 print 函数

2. exec 语句被 python3 废弃,统一使用 exec 函数

3. execfile 语句被 Python3 废弃,推荐使用 exec(open("./filename").read())

4. 不相等操作符""被 Python3 废弃,统一使用"!="

5. long 整数类型被 Python3 废弃,统一使用 int

6. xrange 函数被 Python3 废弃,统一使用 range,Python3 中 range 的机制也进行修改并提高

了大数据集生成效率

7. Python3 中这些方法再不再返回 list 对象:dictionary 关联的 keys()、values()、items(),zip(),

map(),filter(),但是可以通过 list 强行转换:

1. mydict={"a":1,"b":2,"c":3}

2. mydict.keys() #built-in method keys of dict object at 0x000000000040B4C8

3. list(mydict.keys()) #['a', 'c', 'b']

8. 迭代器 iterator 的 next()函数被 Python3 废弃,统一使用 next(iterator)

9. raw_input 函数被 Python3 废弃,统一使用 input 函数

10. 字典变量的 has_key 函数被 Python 废弃,统一使用 in 关键词

11. file 函数被 Python3 废弃,统一使用 open 来处理文件,可以通过 io.IOBase 检查文件类型

12. apply 函数被 Python3 废弃

13. 异常 StandardError 被 Python3 废弃,统一使用 Exception

修改类差异

1. 浮点数除法操作符“/”和“//”的区别

“ / ”:

Python2:若为两个整形数进行运算,结果为整形,但若两个数中有一个为浮点数,则结果为

浮点数;

Python3:为真除法,运算结果不再根据参加运算的数的类型。

“//”:

Python2:返回小于除法运算结果的最大整数;从类型上讲,与"/"运算符返回类型逻辑一致。

Python3:和 Python2 运算结果一样。

2. 异常抛出和捕捉机制区别

Python2

1. raise IOError, "file error" #抛出异常

2. except NameError, err: #捕捉异常

Python3

1. raise IOError("file error") #抛出异常

2. except NameError as err: #捕捉异常

3. for 循环中变量值区别

Python2,for 循环会修改外部相同名称变量的值

1. i = 1

2. print ('comprehension: ', [i for i in range(5)])

3. print ('after: i =', i ) #i=4

Python3,for 循环不会修改外部相同名称变量的值

1. i = 1

2. print ('comprehension: ', [i for i in range(5)])

3. print ('after: i =', i ) #i=1

4. round 函数返回值区别

Python2,round 函数返回 float 类型值

1. isinstance(round(15.5),int) #True

Python3,round 函数返回 int 类型值

1. isinstance(round(15.5),float) #True

5. 比较操作符区别

Python2 中任意两个对象都可以比较

1. 11 'test' #True

Python3 中只有同一数据类型的对象可以比较

1. 11 'test' # TypeError: unorderable types: int() str()

Python3和Python2的区别?

具体区别如下

1:打印时,py2需要可以不需要加括号,py3 需要python 2 :print ('lili') , print 'lili'python 3 : print ('lili') python3 必须加括号exec语句被python3废弃,统一使用exec函数

2:内涵

Python2:1,臃肿,源码的重复量很多。 2,语法不清晰,掺杂着C,php,Java的一些陋习。

Python3:几乎是重构后的源码,规范,清晰,优美。

3: 输出中文的区别python2:要输出中文 需加 # -*- encoding:utf-8 -*-Python3 :直接输出

4:input不同python2 :raw_input python3 :input 统一使用input函数

5:指定字节python2在编译安装时,可以通过参数-----enable-unicode=ucs2 或-----enable-unicode=ucs4分别用于指定使用2个字节、4个字节表示一个unicode;python3无法进行选择,默认使用 ucs4查看当前python中表示unicode字符串时占用的空间:impor sysprint(sys.maxunicode)#如果值是65535,则表示使用usc2标准,即:2个字节表示#如果值是1114111,则表示使用usc4标准,即:4个字节表示

6:py2:xrangerangepy3:range 统一使用range,Python3中range的机制也进行修改并提高了大数据集生成效率

7:在包的知识点里包:一群模块文件的集合 + __init__区别:py2 : 必须有__init__ py3:不是必须的了

8:不相等操作符""被Python3废弃,统一使用"!="

9:long整数类型被Python3废弃,统一使用int

10:迭代器iterator的next()函数被Python3废弃,统一使用next(iterator)

11:异常StandardError 被Python3废弃,统一使用Exception

12:字典变量的has_key函数被Python废弃,统一使用in关键词

13:file函数被Python3废弃,统一使用open来处理文件,可以通过io.IOBase检查文件类型

python3与python2.7相比有什么变化,python3会成为主流吗

python3与python2.7的区别

1.性能 

Py3.0运行 pystone benchmark的速度比Py2.5慢30%。Guido认为Py3.0有极大的优化空间,在字符串和整形操作上可

以取得很好的优化结果。

Py3.1性能比Py2.5慢15%,还有很大的提升空间。

2.编码 

Py3.X源码文件默认使用utf-8编码,这就使得以下代码是合法的:

中国 = 'china'

print(中国)

china

3. 语法 

1)去除了,全部改用!=

2)去除``,全部改用repr()

3)关键词加入as 和with,还有True,False,None

4)整型除法返回浮点数,要得到整型结果,请使用//

5)加入nonlocal语句。使用noclocal x可以直接指派外围(非全局)变量

6)去除print语句,加入print()函数实现相同的功能。同样的还有 exec语句,已经改为exec()函数

例如:

2.X: print "The answer is", 2*2

3.X: print("The answer is", 2*2)

2.X: print x,                              # 使用逗号结尾禁止换行

3.X: print(x, end=" ")                     # 使用空格代替换行

2.X: print                                 # 输出新行

3.X: print()                               # 输出新行

2.X: print sys.stderr, "fatal error"

3.X: print("fatal error", file=sys.stderr)

2.X: print (x, y)                          # 输出repr((x, y))

3.X: print((x, y))                         # 不同于print(x, y)!

7)改变了顺序操作符的行为,例如xy,当x和y类型不匹配时抛出TypeError而不是返回随即的 bool值

8)输入函数改变了,删除了raw_input,用input代替:

2.X:guess = int(raw_input('Enter an integer : ')) # 读取键盘输入的方法

3.X:guess = int(input('Enter an integer : '))

9)去除元组参数解包。不能def(a, (b, c)):pass这样定义函数了

10)新式的8进制字变量,相应地修改了oct()函数。

2.X的方式如下:

0666

438

oct(438)

'0666'

3.X这样:

0666

SyntaxError: invalid token (pyshell#63, line 1)

0o666

438

oct(438)

'0o666'

11)增加了 2进制字面量和bin()函数

bin(438)

'0b110110110'

_438 = '0b110110110'

_438

'0b110110110'

12)扩展的可迭代解包。在Py3.X 里,a, b, *rest = seq和 *rest, a = seq都是合法的,只要求两点:rest是list

对象和seq是可迭代的。

13)新的super(),可以不再给super()传参数,

class C(object):

    def __init__(self, a):

       print('C', a)

class D(C):

    def __init(self, a):

       super().__init__(a) # 无参数调用super()

D(8)

C 8

__main__.D object at 0x00D7ED90

14)新的metaclass语法:

class Foo(*bases, **kwds):

pass

15)支持class decorator。用法与函数decorator一样:

def foo(cls_a):

    def print_func(self):

       print('Hello, world!')

    cls_a.print = print_func

    return cls_a

@foo

class C(object):

pass

C().print()

Hello, world!

class decorator可以用来玩玩狸猫换太子的大把戏。更多请参阅PEP 3129

4. 字符串和字节串 

1)现在字符串只有str一种类型,但它跟2.x版本的unicode几乎一样。

2)关于字节串,请参阅“数据类型”的第2条目

5.数据类型 

1)Py3.X去除了long类型,现在只有一种整型——int,但它的行为就像2.X版本的long

2)新增了bytes类型,对应于2.X版本的八位串,定义一个bytes字面量的方法如下:

b = b'china'

type(b)

type 'bytes'

str对象和bytes对象可以使用.encode() (str - bytes) or .decode() (bytes - str)方法相互转化。

s = b.decode()

s

'china'

b1 = s.encode()

b1

b'china'

3)dict的.keys()、.items 和.values()方法返回迭代器,而之前的iterkeys()等函数都被废弃。同时去掉的还有

dict.has_key(),用 in替代它吧

6.面向对象 

1)引入抽象基类(Abstraact Base Classes,ABCs)。

2)容器类和迭代器类被ABCs化,所以cellections模块里的类型比Py2.5多了很多。

import collections

print('\n'.join(dir(collections)))

Callable

Container

Hashable

ItemsView

Iterable

Iterator

KeysView

Mapping

MappingView

MutableMapping

MutableSequence

MutableSet

NamedTuple

Sequence

Set

Sized

ValuesView

__all__

__builtins__

__doc__

__file__

__name__

_abcoll

_itemgetter

_sys

defaultdict

deque

另外,数值类型也被ABCs化。关于这两点,请参阅 PEP 3119和PEP 3141。

3)迭代器的next()方法改名为__next__(),并增加内置函数next(),用以调用迭代器的__next__()方法

4)增加了@abstractmethod和 @abstractproperty两个 decorator,编写抽象方法(属性)更加方便。

7.异常 

1)所以异常都从 BaseException继承,并删除了StardardError

2)去除了异常类的序列行为和.message属性

3)用 raise Exception(args)代替 raise Exception, args语法

4)捕获异常的语法改变,引入了as关键字来标识异常实例,在Py2.5中:

try:

...    raise NotImplementedError('Error')

... except NotImplementedError, error:

...    print error.message

...

Error

在Py3.0中:

try:

    raise NotImplementedError('Error')

  except NotImplementedError as error: #注意这个 as

    print(str(error))

Error

5)异常链,因为__context__在3.0a1版本中没有实现

8.模块变动 

1)移除了cPickle模块,可以使用pickle模块代替。最终我们将会有一个透明高效的模块。

2)移除了imageop模块

3)移除了 audiodev, Bastion, bsddb185, exceptions, linuxaudiodev, md5, MimeWriter, mimify, popen2,

rexec, sets, sha, stringold, strop, sunaudiodev, timing和xmllib模块

4)移除了bsddb模块(单独发布,可以从获取)

5)移除了new模块

6)os.tmpnam()和os.tmpfile()函数被移动到tmpfile模块下

7)tokenize模块现在使用bytes工作。主要的入口点不再是generate_tokens,而是 tokenize.tokenize()

9.其它 

1)xrange() 改名为range(),要想使用range()获得一个list,必须显式调用:

list(range(10))

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

2)bytes对象不能hash,也不支持 b.lower()、b.strip()和b.split()方法,但对于后两者可以使用 b.strip(b’

\n\t\r \f’)和b.split(b’ ‘)来达到相同目的

3)zip()、map()和filter()都返回迭代器。而apply()、 callable()、coerce()、 execfile()、reduce()和reload

()函数都被去除了

现在可以使用hasattr()来替换 callable(). hasattr()的语法如:hasattr(string, '__name__')

4)string.letters和相关的.lowercase和.uppercase被去除,请改用string.ascii_letters 等

5)如果x y的不能比较,抛出TypeError异常。2.x版本是返回伪随机布尔值的

6)__getslice__系列成员被废弃。a[i:j]根据上下文转换为a.__getitem__(slice(I, j))或 __setitem__和

__delitem__调用

7)file类被废弃,在Py2.5中:

file

type 'file'

在Py3.X中:

file

Traceback (most recent call last):

File "pyshell#120", line 1, in module

 file

NameError: name 'file' is not defined

python3--内置函数

python的常用内置函数

1.abs() 函数返回数字的绝对值

abs(-40)=40

2. dict() 函数用于创建一个字典

dict()

{}      #创建一个空字典类似于u={},字典的存取方式一般为key-value

例如u = {"username":"tom",  "age":18}

3. help() 函数用于查看函数或模块用途的详细说明

help('math')查看math模块的用处

a=[1,2,3,4]

help(a)查看列表list帮助信息

4.dir()获得当前模块的属性列表

dir(help)

['__call__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

5.min() 方法返回给定参数的最小值 /参数可以为序列

a=  min(10,20,30,40)

a

10

6. next() 返回迭代器的下一个项目

it = iter([1, 2, 3, 4, 5])

next(it)

1

next(it)

2

7. id() 函数用于获取对象的内存地址

a=12

id(a)

1550569552

8.enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

a=["tom","marry","leblan"]

list(enumerate(a))

[(0, 'tom'), (1, 'marry'), (2, 'leblan')]

9. oct() 函数将一个整数转换成8进制字符串

oct(15)

'0o17'

oct(10)

'0o12'

10. bin() 返回一个整数 int 或者长整数 long int 的二进制表示

bin(10)

'0b1010'

bin(15)

'0b1111'

11.eval() 函数用来执行一个字符串表达式,并返回表达式的值

eval('2+2')

4

12.int() 函数用于将一个字符串会数字转换为整型

int(3)

3

int(3.6)

3

int(3.9)

3

int(4.0)

4

13.open() 函数用于打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写

f=open('test.txt')

14.str() 函数将对象转化为适于人阅读的形式

str(3)

'3'

15. bool() 函数用于将给定参数转换为布尔类型,如果没有参数,返回 False

bool()

False

bool(1)

True

bool(10)

True

bool(10.0)

True

16.isinstance() 函数来判断一个对象是否是一个已知的类型

a=5

isinstance(a,int)

True

isinstance(a,str)

False

17. sum() 方法对系列进行求和计算

sum([1,2,3],5)

11

sum([1,2,3])

6

18. super() 函数用于调用下一个父类(超类)并返回该父类实例的方法。super 是用来解决多重继承问题的,直接用类名调用父类方法

class   User(object):

  def__init__(self):

class Persons(User):

        super(Persons,self).__init__()

19. float() 函数用于将整数和字符串转换成浮点数

float(1)

1.0

float(10)

10.0

20. iter() 函数用来生成迭代器

a=[1,2,3,4,5,6]

iter(a)

for i in iter(a):

...         print(i)

...

1

2

3

4

5

6

21.tuple 函数将列表转换为元组

a=[1,2,3,4,5,6]

tuple(a)

(1, 2, 3, 4, 5, 6)

22.len() 方法返回对象(字符、列表、元组等)长度或项目个数

s = "playbasketball"

len(s)

14

a=[1,2,3,4,5,6]

len(a)

6

23. property() 函数的作用是在新式类中返回属性值

class User(object):

 def __init__(self,name):

          self.name = name

def get_name(self):

          return self.get_name

@property

 def name(self):

         return self_name

24.type() 函数返回对象的类型

25.list() 方法用于将元组转换为列表

b=(1,2,3,4,5,6)

list(b)

[1, 2, 3, 4, 5, 6]

26.range() 函数可创建一个整数列表,一般用在 for 循环中

range(10)

range(0, 10)

range(10,20)

range(10, 20)

27. getattr() 函数用于返回一个对象属性值

class w(object):

...             s=5

...

a = w()

getattr(a,'s')

5

28. complex() 函数用于创建一个复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数

complex(1,2)

(1+2j)

complex(1)

(1+0j)

complex("1")

(1+0j)

29.max() 方法返回给定参数的最大值,参数可以为序列

b=(1,2,3,4,5,6)

max(b)

6

30. round() 方法返回浮点数x的四舍五入值

round(10.56)

11

round(10.45)

10

round(10.45,1)

10.4

round(10.56,1)

10.6

round(10.565,2)

10.56

31. delattr 函数用于删除属性

class Num(object):

...    a=1

...    b=2

...    c=3.

.. print1 = Num()

print('a=',print1.a)

a= 1

print('b=',print1.b)

b= 2

print('c=',print1.c)

c= 3

delattr(Num,'b')

print('b=',print1.b)

Traceback (most recent call last):  File "", line 1, inAttributeError: 'Num' object has no attribute 'b'

32. hash() 用于获取取一个对象(字符串或者数值等)的哈希值

hash(2)

2

hash("tom")

-1675102375494872622

33. set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。

a= set("tom")

b = set("marrt")

a,b

({'t', 'm', 'o'}, {'m', 't', 'a', 'r'})

ab#交集

{'t', 'm'}

a|b#并集

{'t', 'm', 'r', 'o', 'a'}

a-b#差集

{'o'}


本文标题:python3函数性能,python三个特性
当前地址:http://kswsj.cn/article/hcisgs.html

其他资讯