您的位置:首页 > 编程语言 > Python开发

脚本语言Python 3学习

2018-01-15 21:34 204 查看
Python中,采用的格式化方式和C语言是一致的。Python有两个版本,一个是2.x版,一个是3.x版,这两个版本是不兼容的。

Python 3版本- https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000 Python学习- http://blog.csdn.net/qq_21972583/article/category/7068955/2
learn-python3- https://github.com/michaelliao/learn-python3/tree/master/samples
awesome-python3-webapp - https://github.com/michaelliao/awesome-python3-webapp/
>推荐两款文本编辑器:一个是Sublime Text;一个是Notepad++

>通过命令给hello.py以执行权限:$ chmod a+x hello.py

执行Python文件: >>> python hello.py

Python函数调用:

def power(x):

    return x * x

>>> power(5)

25

>递归:使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。

 解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。

 尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

>Python高级特性:切片、 迭代、 列表生成式 、生成器 、迭代器

要改成尾递归方式,需要多一点代码,主要是要把每一步的乘积传入到递归函数中:

def fact(n):

    return fact_iter(n, 1)

def fact_iter(num, product):

    if num == 1:

        return product

    return fact_iter(num - 1, num * product)

在Python中,代码不是越多越好,而是越少越好。代码不是越复杂越好,而是越简单越好。

Python提供了切片(Slice)操作符:

>>> L[0:3]

['Michael', 'Sarah', 'Tracy']

L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。

因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。

默认情况下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for k, v in d.items()。

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11)):

>>> [x * x for x in range(1, 11)]

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

>>> L = [x * x for x in range(10)]

>>> L

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

>>> g = (x * x for x in range(10))

>>> g
<generator object <genexpr> at 0x1022ef630>

generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

>>> f = fib(6)

>>> f

<generator object fib at 0x104feaaa0>

迭代器:可以使用isinstance()判断一个对象是否是Iterable对象;可以使用isinstance()判断一个对象是否是Iterator对象

直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如list、tuple、dict、set、str等;

一类是generator,包括生成器和带yield的generator function。

函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。

函数式编程(请注意多了一个“式”字)——Functional Programming,虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算。

计算机(Computer)和计算(Compute)的概念:

在计算机的层次上,CPU执行的是加减乘除的指令代码,以及各种条件判断和跳转指令,所以,汇编语言是最贴近计算机的语言。

而计算则指数学意义上的计算,越是抽象的计算,离计算机硬件越远。

对应到编程语言,就是越低级的语言,越贴近计算机,抽象程度低,执行效率高,比如C语言;越高级的语言,越贴近计算,抽象程度高,执行效率低,比如Lisp语言。

函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。

函数本身也可以赋值给变量,即:变量可以指向函数。

Python内建的filter()函数用于过滤序列。计算素数的一个方法是埃氏筛法。

  在面向对象(OOP)的设计模式中,decorator被称为装饰模式。OOP的装饰模式需要通过继承和组合来实现,而Python除了能支持OOP的decorator外,直接从语法层次支持decorator。Python的decorator可以用函数实现,也可以用类实现。

  在Python中,一个.py文件就称之为一个模块(Module)。使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中。为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。

  自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模块,自己的模块就不可命名为sys.py,否则将无法导入系统自带的sys模块。

  创建自己的模块时,要注意:

1.模块名要遵循Python变量命名规范,不要使用中文、特殊字符;

2.模块名不要和系统模块名冲突,最好先查看系统是否已存在该模块,检查方法是在Python交互环境执行import abc,若成功则说明系统存在此模块。

------------------------

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

' a test module '

__author__ = 'Michael Liao'

import sys

def test():

    args = sys.argv

    if len(args)==1:

        print('Hello, world!')

    elif len(args)==2:

        print('Hello, %s!' % args[1])

    else:

        print('Too many arguments!')

if __name__=='__main__':

    test()

$ python3 hello.py

Hello, world!

$ python hello.py Michael

Hello, Michael!

-----------------------

在Python中,安装第三方模块,是通过包管理工具pip完成的。

如果你正在使用Mac或Linux,安装pip本身这个步骤就可以跳过了。

如果你正在使用Windows,请参考安装Python一节的内容,确保安装时勾选了pip和Add python.exe to Path。

在命令提示符窗口下尝试运行pip,如果Windows提示未找到命令,可以重新运行安装程序添加pip。

注意:Mac或Linux上有可能并存Python 3.x和Python 2.x,因此对应的pip命令是pip3。

面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

面向对象的设计思想是抽象出Class,根据Class创建Instance。

面向对象的抽象程度又比函数要高,因为一个Class既包含数据,又包含操作数据的方法。

数据封装、继承和多态是面向对象的三大特点。

 面向对象最重要的概念就是类(Class)和实例(Instance),必须牢记类是抽象的模板,比如Student类,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。

和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别,所以,你仍然可以用默认参数、可变参数、关键字参数和命名关键字参数。

class Student(object):

    def __init__(self, name, score):

        self.name = name

        self.score = score

在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。

静态语言 vs 动态语言:动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的。

对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。

对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了:

class Timer(object):

    def run(self):

        print('Start...')

这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。

Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个read()方法,返回其内容。但是,许多对象,只要有read()方法,都被视为“file-like object“。许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了read()方法的对象。

判断对象类型,对象是什么类型、有哪些方法呢,使用type()函数

对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数。

总是优先使用isinstance()判断类型,可以将指定类型及其子类“一网打尽”。

面向对象高级编程:多重继承、定制类、枚举类、元类等概念、__slots__、@property

通过callable()函数,我们就可以判断一个对象是否是“可调用”对象。

除了使用type()动态创建类以外,要控制类的创建行为,还可以使用metaclass。metaclass,直译为元类。

高级语言通常都内置了一套try...except...finally...的错误处理机制,Python也不例外。

Python内置的logging模块可以非常容易地记录错误信息。用raise语句抛出一个错误的实例。

启动Python解释器时可以用-O参数来关闭assert。测试驱动开发”(TDD:Test-Driven Development),单元测试。

re模块- https://docs.python.org/3/library/re.html
Python内置的“文档测试”(doctest)模块可以直接提取注释中的代码并执行测试。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: