第一章 Python简介

全览:
Python的大部分基本特性:如变量、表达式、控制流、函数、生成器、类和输入\输出;
Python3和Python2.6的区别:大多数与打印和I/O有关;
 
--------------------------------------
1.1  运行Python
 知识点:Python程序是由解释器来执行的;
 解释器和Python开发环境存在多种实现(Jython、IronPython、IDLE、ActivePython、WingIDE、pydev等),
 例子1、读入-求值循环:    “>”是大于号,“<”是小于号
 (venv) D:\excel\Python参考手册>python
 Python 3.6.7 (v3.6.7:6ec5cf24b7, Oct 20 2018, 13:35:33) [MSC v.1900 64 bit (AMD64)] on win32
 Type "help", "copyright", "credits" or "license" for more information.
 >>> print("Hello World")
 Hello World
 
 例子2、桌面计算器:
 >>> 6000 + 4523.50 + 134.12
 10657.62
 >>> _ + 8192.32
 18849.940000000002
 >>>
 
 例子3、创建可以重复运行的程序:
 # helloworld.py
 print("Hello World")
 % python helloworld.py
 Hello World
 
 例子4、在UNIX中,可以在程序的首行中使用#!
 #!/usr/bin/env python
 print("Hello World")
 
 例子5、退出程序:UNIX中,EOF(文件结束)Ctrl+D,而在Windows中则是Ctrl+Z(或F6),>>> raise SystemExit;
 
1.2 变量和算术表达式
 例子1、简单的复利计算  (说明变量和表达式的用法)
 principal = 1000    # 初始金额
 rate = 0.05    # 利率
 numyears = 5  # 年数
 year = 1
 while year <= numyears:
  principal = principal * (1 + rate)
  print(year, principal)
  year += 1
 print("==============================")
 print("%3d  %0.2f" % (year, principal))
 print("==============================")
 print("{0:3d} {1:0.2f}".format(year, principal))
 ========================================================
 1、Python事一种动态类型的语言;
 2、赋值运算符的作用仅仅是在名称和值之间创建一种关联;
 3、变量名称会被绑定到不同的值,这些值可以属于不同的类型,但变量名称是无类型的;
 4、缩进一般是4个空格,一个Tab键;
 5、实现右对齐,并将principal的精度限制为两位,字符串格式化运算符%;
 6、更新潮的字符串格式化的方法是使用format()函数单独格式化每个部分;
 7、{0:3d} {1:0.2f}".format(year, principal) 中冒号前的数字代表传递给format()方法的相关参数,而冒号后的部分则是格式说明符;
1.3 条件语句
 例子1、if与else语句可执行简单的检验:
 if a < b:
  print ("Computer says Yes")
 else:
  print ("Computer says No")
 例子2、要创建一条空子句,可以使用pass语句:
  if a < b:
   pass
  else:
   print ("Computer says No")
 例子3、使用or、and和not关键字可以组成布尔表达式:
 if product == "game" and type == "pirate memory" \
   and not (age < 4 or age > 8):
   print("I'll take it")
 
 知识点:Python没有专门的switch或case语句用于检测多个值。要处理多个检验条件,可以使用elif语句;
 例子4、
 if suffix == ".htm":
  content = 'text/html'
 elif suffix == ".jpg":
  content = "image/jpeg"
 elif suffix == ".png":
  content = "image/png"
 else:
  raise RuntimeError("Unknown content type")
 例子5、要表示真值,可以使用布尔值True和False
 if 'spam' is s:
  has_spam = True
 else:
  has_spam = False
  
 第二种写法:has_spam = 'spam' in s
 
1.4 文本输入和输出
 例子1、打开一个文件并逐行读取该文件的内容:
 f = open("foo.txt")
 line = f.readline()
 while line:
  #print(line)
  print(line, end='')
  #print("==========")
  line = f.readline()
 f.close()
 例子2、打开一个文件将内容写入文件:
 principal = 1000    # 初始金额
 rate = 0.05    # 利率
 numyears = 5  # 年数
 year = 1
 f = open("out", "w")
 f.seek(0, 2)
 while year <= numyears:
  principal = principal * (1 + rate)
  # print(year, principal)
  print("%3d  %0.2f" % (year, principal), file=f)
  year += 1
 例子3、解释器输出流和输入流(交互式读取用户输入,文件sys.stdin读取,数据输出到屏幕上,可以写入文件sys.stdout中,这与在print语句所生成数据时所用的文件是同一个文件):
 import sys
 sys.stdout.write("Enter your name :")
 name = sys.stdin.readline()
 
1.5 字符串
 知识点:要创建一个字符串字面量,将字符串放在单引号、双引号或三引号中即可
 a = "Hello World"
 b = 'Python is groovy'
 c = """Computer says 'No'"""
 知识点:单引号和双引号指定的字符串必须放在一个逻辑行上,多行的字符串要用三引号表示:
 print("""Content-type: text/html
 <h1> Hello World </h1>
 Click <a href="http://www.python.org">here</a>.           
 """)
 知识点:字符串存储在一个字符序列中,这个字符序列使用整数作为索引,索引从0开始。要提取其中的一个字符,可以使用索引运算符s[i]:
 a = "Hello World"
 b = a[1]
 print("b:", b)
 知识点:提取一个子字符串,可以使用切片运算符s[i:j]:   i<=k<j
 c = a[:5]  
 d = a[6:]
 e = a[3:8]
 知识点:可以使用(+)运算符连接两个字符串:
 g = a + " This is a test"
 知识点:Python不会把字符串的内容隐式地解释为数值数据(Perl或PHP等语言中会这样解释)。+运算符始终会连接字符串:
 x = "37"
 y = "42"
 z = x + y
 知识点:要执行数学计算,首先要使用int()或float()等函数将字符串转换为数值:
 z = int(x) + int(y)
 知识点:使用str()、repr()或format()函数可将非字符串值转换为字符串表示形式:
 s = "The value of x is " + str(x)
 s = "The value of x is " + repr(x)
 s = "The value of x is " + format(x, "4d")
 知识点:str()生成地输出与print语句得到的输出相同,而用repr()创建的字符串可表示程序中某个对象的精确值:
 >>> x = 3.4
 >>> str(x)
 '3.4'
 >>> repr(x)
 '3.4'
 知识点:双精度浮点数、底层计算机硬件无法精确地表示十进制小数;
 知识点:format()函数可将值转换成特定格式等字符串:
 >>> x = 3.45
 >>> format(x, "0.5f")
 '3.45000'
1.6 列表
 知识点:定义、列表是任意对象组成的序列;
 names = ["Dave", "Mark", "Ann", "Phil"]
 知识点:列表使用从0开始的整数索引,使用索引运算符可以访问并修改列表中的项:
 a = names[2]
 print("a:", a)
 names[0] = "Jeff"
 print("names[0]:", names[0])
 知识点:要将新项追加到列表末尾,可使用append()方法:
 names.append("Paula")
 print("names:", names)
 知识点:要将一项插入到列表中,可使用insert()方法:
 names.insert(2, "Paula")
 print("names:", names)
 知识点:使用切片运算符可以提取一个子列表或对子列表重新赋值:
 b = names[0:2]
 print("b:", b)
 c = names[2:]
 names[1] = 'Jeff'
 names[0:2] = ['Dave', 'Mark', 'Jeff']
 知识点:使用加号(+)可以连接列表:
 a = [1, 2, 3] + [4, 5]
 知识点:创建一个空列表有两种方式:
 names = []
 names = list()
 知识点:列表可以包含任意种类的Python对象,包括其他列表在内,嵌套列表中包含的项需要使用多次索引操作才能访问到:
 a = [1, "Dave", 3.14, ["Mark", 7, 9, [100, 101]], 10]
 a[1]
 a[3][2]
 a[3][3][1]
 知识点:展示列表中的一些高级特性:
 
1.7 元组
 知识点:要创建简单的数据结构,可以使用元组将一组值打包到一个对象中。在圆括号中放入一组值即可创建元组,
 stock = ('GOOG', 100, 490.10)
 address = ('www.python.org', 80)
 person = (first_name, last_name, phone)
 知识点:即使没有圆括号,Python通常也能识别出元组:
 stock = 'GOOG', 100, 490.10
 address = 'www.python.org', 80
 person = first_name, last_name, phone
 知识点:可以定义0个和1个元素的元组,但语法较为特殊:
 a = ()
 b = (item, )
 c = item,
 知识点:可以使用数字索引来提取元组中的值。更常见的做法是将元组解包为一组变量:
 name, shares, price = stock
 host, port = address
 first_name, last_name, phone = person
 知识点:元组支持的大部分操作与列表的相同(如索引、切片和连接),但创建元组后不能修改它的内容(也就是说无法替换、删除现有元组中的元素,或者向现有元组中添加元素)。这说明最好把元组看成一个由多个部分组成的单一对象,而不是可在其中插入或删除项的不同对象的集合。
 知识点:程序创建了大量的小列表(即包含的项少于十来个),则会造成内存浪费。这是因为系统会为列表分配稍微多一些内存,以优化添加新项的操作的性能。而由于元组是不可变的,所以它们的展现更为紧凑,不会占据额外的内存空间。
 知识点:表示数据时,经常同时经常使用元组和列表。
 例子:如何读取包含不同数据列,且各数据列由逗号隔开的文件:
 filename = "portfolio.csv"
 portfolio = []
 for line in open(filename):
  fields = line.split(",")   # 将每行划分为一个列表
  name = fields[0]         # 提取并转换每个字段
  shares = int(fields[1])
  price = float(fields[2])
  stock = (name, shares, price)  # 创建一个元组(name, shares, price)
  portfolio.append(stock) # 将记录追加到列表中
 print("portfolio:", portfolio)
 知识点:字符串的split()方法会按照指定的分隔符将一个字符串划分为一个字段列表。该程序最后创建的portfolio数据结构类似一个二维的行列数组,每行由一个元组表示,并可通过如下方法访问:
 print("portfolio:", portfolio[0][0])
 portfolio: "周海武1 "
 知识点:下面给出了一种循环访问所有记录并将字段展开到一组变量中的简单方法:
 total = 0.0
 for name, shares, price in portfolio:
  total += shares * price
 print("total:", total)
 
1.8 集合   set
 知识点:集合用于包含一组无序的对象。要创建集合,可使用set()函数并像下面这样提供一系列的项:
 s = set([3,5,9,10])
 t = set("Hello")
 知识点:与列表和元组不同,集合是无序的,也无法通过数字进行索引。此外,集合中的元素不能重复:
 >>> t = set("Hello")
 >>> t
 {'l', 'e', 'o', 'H'}
 知识点:集合支持一系列标准操作,包括并集、交集、差集和对称差集:
 a = t | s    # t和s的并集
 b = t & s    # t和s的交集
 c = t - s    # 差集(项在t中,但不在s中)
 d = t ^ s    # 对称差集(项在t或s中,但不会同时出现在二者中)
 知识点:使用add()和update()可以在集合中添加新项:
 t.add('x')
 s.update([10,37,42])
 知识点:使用remove()可以删除一项:
 t.remove('H')
1.9 字典
 知识点:字典就是一个关联数组或散列表,其中包含通过键(key)索引的对象。在大括号({})中放入值即可创建字典:
 stock = {
  "name": "GOOG",
  "shares": 100,
  "price": 490.10,
 }
 知识点:
 要访问字典成员,可使用键索引运算符:
 name  = stock["name"]
 value = stock["shares"] * stock["price"]
 知识点;字符串是最常用的键类型,还可以使用其他的Python对象,包括数值和元组。但包括列表和字典在内的一些对象不能用作键,因为它们的内容可以发生变化。
 知识点:字典也可用作快速查找无序数据的一个容器。
 stock = {
  "name": "GOOG",
  "shares": 100,
  "price": 490.10,
 }
 知识点:创建一个空字典的两种方式:
 prices = {}   # 一个空字典
 prices = dict()  # 一个空字典
 知识点:使用int运算符可以检验某个内容项是不是字典成员:
 if "SCOX" in prices:
  p = prices["SCOX"]
 else:
  p = 0.0
  
 p = prices.get("SCOX", 0.0)
 print("p:", p)
 知识点:要获得一个字典关键字的列表,将字典转换为列表即可:
 syms = list(prices)
 print("syms:", syms)
 知识点:使用del语句可以删除字典的元素:
 del prices["MSFT"]
 知识点:字典可能是Python解释器中最完善的数据类型。因此,如果只是要在程序中存储和处理数据,使用字典比使用一些自定义数据结构要好得多。
 
1.10 迭代与循环
 最常用的循环结构是for语句,它可以用来对容器成员进行迭代操作。迭代时Python中内涵最丰富的功能之一。但最常见的迭代形式是简单循环访问一个序列(如字符串、列表或元组)的所有成员:
 for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
  print ("2 to the %d power is %d" % (n, 2**n))
  
 for n in range(1, 10):
  print("2 to the %d power is %d" % (n, 2 ** n))
  
 知识点:range(i, j, [, 不长])函数创建的对象表示值在i和j-1之间的整数范围。如果起始值i被省略,则认为是0。第三个参数是可选的步长值:
 a = range(5)
 for i in a:
  print("i:", i)
 b = range(1, 8)
 for i in b:
  print("i:", i)
 c = range(0, 14, 3)
 for i in c:
  print("i:", i)
 d = range(8, 1, -1)
 for i in d:
  print("i:", i)
 知识点:Python 2 ,range函数创建的值是已经用整数值完全填满的列表。当范围非常大时,这可能会在不经意间耗掉所有可用内存。
 可能会看到程序员使用另一个函数xrange(),xrange()函数创建的对象会在收到查询请求时根据需要计算它所表示的值。
 因此它成为了表示极大范围整数值的首选方式。在Python 3中,xrange()函数已经更名为range(),并且已删除了老式range()函数的功能。
 知识点:for语句并不仅限于处理整数序列,还可用于迭代多种对象,包括字符串、列表、字典和文件:
 a = "Hello World"
    # 打印出a中的每个字符
    for c in a:
        print(c)
   
    b = ["Dave", "Mark", "Ann", "Phil"]
    # 打印出一个列表的成员
    for name in b:
        print(name)
   
    c = {'GOOG': 490.10, 'IBM': 91.50, 'AAPL': 123.15}
    # 打印出一个字典的所有成员
    for key in c:
        print(key, c[key])
   
    # 打印一个文件中的所有行
    f = open("foo.txt")
    for line in f:
        print( line,)
 知识点:for循环是Python最强大的语言特性之一,因为你可以创建自定义的迭代器对象和生成器函数,为它提供值序列。
 
1.11 函数
 知识点:使用def语句可以创建函数:
 def remainder(a, b):
  q = a // b
  r = a - q*b
  return r
 知识点:要调用函数,只要使用函数名加上用圆括号括起来的参数即可,如result = remainder(37, 15)
 知识点:如果要让函数返回多个值,可以使用元组:
 def remainder(a, b):
  q = a // b
  r = a - q*b
  return (q, r)
 知识点:使用元组返回多个值时,可以很容易地将结果解包到单独的变量中:
  quotient, remainder = divide(1456, 33)
 知识点:要给函数参数提供一个默认值,可使用以下赋值方式:
  def connect(hostname, port, timeout=300):
   #函数体
 知识点:在函数定义中给一个参数提供默认值以后,调用此函数时就可以省略该参数,此时该参数将使用默认值,
  connect('www.python.org', 80)
 知识点:还可以使用关键字参数调用函数,此时可以按任意顺序提供参数,但这需要你知道函数定义中的参数名称:
  connect(port=80, hostname="www.python.org")
 知识点:在函数中创建变量或给变量赋值时,该变量的作用域时局部的。也就是说,该变量只定义在函数体内部,而且当函数返回值后会立即销毁该变量。
 要在函数内部修改某个全局变量的值,可以使用global语句:
 count = 0
 ...
 def foo():
  global count
  count += 1   # 更改全局变量 count
  
1.12 生成器
 知识点:如果使用yield语句,可以让函数生成一个结果序列,而不仅仅是一个值:
 def countdown(n):
    print("Counting down!")
    while n > 0:
        yield n   # 生成一个值(n)
        n -= 1
 知识点:任何使用yield的函数都称为生成器。调用生成器函数将创建一个对象,该对象通过连续调用__next__()方法生成一系列的结果:
 >>> def countdown(n):
 ...     print("Counting down!")
 ...     while n > 0:
 ...         yield n   # 生成一个值(n)
 ...         n -= 1
 ...
 >>> c = countdown(5)
 >>> c.__next__()
 Counting down!
 5
 >>> c.__next__()
 4
 >>> c.__next__()
 3
 >>> c.__next__()
 2
 >>> c.__next__()
 1
 知识点:生成器是编写基于处理管道、流或数据流程序的一种极其强大的方式。例如,下面的生成器函数模拟了常用于监控日志文件的UNIX tail -f命令的行为:
 
 import time
 def tail(f):
  f.seek(0, 2)   #  移动到EOF
  while True:
   line = f.readline()   #  尝试读取一个新的文件行
   if not line:    #  如果没有内容,暂时休眠并再次尝试
    time.sleep(0.1)
    continue
   yield line
 知识点:下面的生成器用于在很多行中查找特定的子字符串:
 def grep(lines, searchtext):
    for line in lines:
        if searchtext in line:
            yield line
 知识点:下面的例子将以上两个生成器合并在一起,创建了一个简单的处理管道:(UNIX "tail -f | grep python"命令的python实现)
 wwwlog = tail(open("access-log.txt"))
 pylines = grep(wwwlog, "python")
 for line in pylines:
  print(line)
 知识点:生成器的微妙之处在于,它经常和其他可迭代的对象(如列表或文件)混合在一起。特别是在编写如for item in s这样的语句时,s可以代表一个列表、文件的各行、生成器函数的结果,或者支持迭代的其他任何对象。能够在s中插入不同对象,为创建可扩展的程序提供了一个强大的工具。
 
1.13 协程
 知识点:函数运行时要使用单一的一组输入参数。但是,函数也可以编写成一个任务程序,用来处理发送给它的一系列输入。这类函数被称为协程,它是通过将yield语句作为表达式(yield)的形式创建的:
 def print_matches(matchtext):
    print("Looking for", matchtext)
    while True:
        line = (yield)
        if matchtext in line:
            print(line)
 matcher = print_matches("python")
 matcher.__next__()    # 向前执行到第一条(yield)语句
 matcher.send("Hello World")
 matcher.send("python is cool")
 
 matcher.send("yow!")
 matcher.close()  # matcher函数调用结束
 
 知识点:使用send()为协程发送某个值之前,协程会暂时中止。发送值之后,协程中的(yield)表达式将返回这个值,而接下来的语句将会处理它。处理直到遇到下一个(yield)表达式才会结束。这时函数将暂时中止。正如上一个例子所示,这个过程将会继续下去,直到协程函数返回或者调用它的close()方法为止。
 
 知识点:基于生产者-消费者(即程序的一部分生成的数据会被程序的另一部分使用)编写并发程序时,协程十分有用。在这种模型中,协程代表了数据的一个消费者。
 例子:一起使用生成器和协程的一个例子:
 # 一组匹配器协程
 matchers = [
  print_matches("python"),
  print_matches("guido"),
  print_matches("jython")
 ]
 # 通过调用next()准备所有的匹配器
 for m in matcher:
  m.next()
 
 #将一个活跃的日志文件传递给所有的匹配器, 注意,为保证运行正常,
 # 必须有一台Web服务器持续将数据写入日志
 wwwlog = tail(open("access-log.txt"))
 for line in wwwlog:
  for m in matchers:
   m.send(line)  # 将数据发送到每个匹配器协程中
 
 
1.14 对象和类
 知识点:程序中使用的所有值都是对象。对象由内部数据和各种方法组成,这些方法会执行与这些数据相关的各种操作。前面在处理像字符串和列表这样的内置类型时,就已经用到了对象和方法。
 items = [37, 42] # 创建一个列表对象
 items.append(73) # 调用append()方法
 知识点:dir()函数可以列出对象上的可用方法,是进行交互式实验的有用工具,例如:
 >>> item = [37, 42]
 >>> dir(item)
 ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getite
 m__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new_
 _', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'appen
 d', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
 >>>
 知识点:查看对象时,会看到诸如append()和insert()等很熟悉的方法。但也可以看到固定以双下划线开始和结束的特殊方法。这些方法用于实现各种语言运算。
 例如,__add__()方法实现了+运算符的功能:
 >>> item.__add__([73, 101])
 [37, 42, 73, 101]
 知识点:class语句用于定义新的对象类型,实现面向对象编程。例如,下面的类定义了一个支持push()、pop()和length()操作的简单栈:
 class Stack(object):
    def __init__(self):
        self.stack = [ ]   # 初始化栈
    def push(self, object):
        self.stack.append(object)
    def pop(self):
        return self.stack.pop()
    def length(self):
        return len(self.stack)
 知识点:在类定义的第一行中,语句class Stack(object)将Stack声明为一个object。使用圆括号是Python指定继承的方式---在这个例子中,Stack继承自object,object也是所有Python类型的根类型。类定义中使用def语句定义了方法。每个方法中的第一个参数始终指向对象本身。根据约定,该参数的名称为self。涉及对象属性的所有操作都必须显式引用self变量。以双下划线开始和结束的方法是特殊的方法。例如,__init__用于在创建对象后初始化该对象。
 知识点:要想使用类,可编写如下所示的代码:
 s = Stack()    #  创建一个栈
 s.push("Dave") # 在栈中放入一些内容
 s.push(42)
 s.push([3, 4, 5])
 x = s.pop()  # x的值为[3, 4, 5]
 y = s.pop()  # y的值为42
 del s        # 删除s
 知识点:这个例子创建了一个全新的对象来实现栈。但是,栈与内置的列表对象几乎完全相同。因此,继承list然后添加一个额外的方法也是可行的:
 class Stack(list):
    # 为栈接口添加push()方法
    # 注意:列表已经提供了一个pop()方法
    def push(self, object):
        self.append(object)
 知识点:通常,类中定义的所有方法只适用于该类的实例(即创建的对象)。但是,也可以定义不同种类的方法,如C++和Java程序员所熟知的静态方法,例如:
 class EventHanlder(object):
    @staticmethod
    def dispatcherThread():
        while (1):
            # 等待请求
            ...
 EventHanlder.dispatcherThread()   # 像函数一样调用方法
 知识点:在这个例子中,@staticmethod将方法声明为静态方法。@staticmethod是使用装饰器(decorator)的一个例子。
1.15 异常
 知识点:如果程序中出现错误,就会引发异常,并显示类似下面的回溯消息:
 Traceback (most recent call last):
 File "foo.py", line 12, in <module>
 IOError: [Errno 2] No such file or directory: 'file.txt'
 知识点:该回溯消息指出了所发生的错误类型及位置。通常情况下,错误会导致程序终止。但是可以使用try和except语句捕捉并处理异常:
 try:
  f = open("file.txt", "r")
 except IOError as e:
  print(e)
 知识点:如果出现IOError,引发错误的详细信息将被放在对象e中,然后控制权被传递给except代码块中的代码。如果出现其他类型的异常,对象e将被传递给用于处理这些异常的代码块(如果有的话)。如果没有出现错误,except代码块中的代码将被忽略。处理完异常后,程序将继续执行紧跟在最后一个except代码块后面的语句。程序不会返回到发生异常的位置。
 知识点:raise语句用于手工引发异常。引发异常时,可以使用任意一个内置异常,如下所示:
 raise RuntimeError("Computer says no")
 知识点:在进行异常处理时,如何正确地管理系统资源(如锁、文件和网络连接)通常是一个棘手地问题。为了简化此类编程,可以对某些种类的对象使用with语句。下面的例子给出了使用互斥锁的代码:
 import threading
 message_lock = threading.Lock()
 ...
 with message_lock:
  messages.add(newmessage)
 知识点:在这个例子中,with语句执行时会自动获取message_lock对象。当执行离开with代码块上下文后,锁将被自动释放。不管with代码块内部发生了什么,都会出现这种管理行为。例如,如果出现一个异常,当控制离开代码块环境时锁也将被释放。
 知识点:with语句通常只适用于系统资源或执行环境相关的对象,如文本、连接和锁。但是,用户定义的对象也可以定义自己的自定义处理机制。
 
1.16 模块
 知识点:随着程序变得越来越大,为了便于维护,需要把它分为多个文件。为此,Python允许把定义放入一个文件中,然后在其他程序和脚本中将其作为模块导入。要创建模块,可将相关的语句和定义放入与模块同名的文件中(注意,该文件的后缀必须是.py):
 def divide(a, b):
    q = a/b
    r = a - q*b
    return (q,r)
 知识点:要在其他程序中使用该模块,可以使用import语句:
 import div
 a, b = div.divide(2305, 29)
 知识点:import语句创建了一个新的命名空间,并在该命名空间中执行与.py文件相关的所有语句。要在导入后访问命名空间的内容,只要使用该模块的名称作为前缀,正如上面例子中的div.divide()一样。
 
 知识点:如果要使用不同的名称导入模块,可以给import语句加上可选的as限定符:
 import div as foo
 a, b = foo.divide(2305, 29)
 
 知识点:要把模块的所有内容加载到当前的命名空间中,还可以使用以下语句:
 from div import *
 知识点:与对象一样,dir()函数可以列出模块的内容,是进行交互式实验的有用工具:
 >>> import string
 >>> dir(string)
 ['Formatter', 'Template', '_ChainMap', '_TemplateMetaclass', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__pa
 ckage__', '__spec__', '_re', '_string', 'ascii_letters', 'ascii_lowercase', 'ascii_uppercase', 'capwords', 'digits', 'hexdigits', 'octdigits', 'printable',
 'punctuation', 'whitespace']
 >>>
1.17 获得帮助
 知识点:使用Python时,有几个快速获取可用信息的来源。首先,以交互模式运行Python时,可以使用help()命令获得有关内置模块和Python其他方面的信息。单独输入help()将获得一般信息,而输入help('模块名')则可获得具体模块的信息。如果提供函数名称,help()命令还可以返回该函数的详细信息。
 知识点:大多数Python函数都有描述该函数用途的文档字符串。要打印这个文档字符串,只要打印__doc__属性即可。
 >>> print(issubclass.__doc__)
 Return whether 'cls' is a derived from another class or is the same class.
 
 A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to
 check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)
 or ...`` etc.
 知识点:最后但也很重要的一点是,大多数Python安装还包括了命令pydoc。该命令用于返回有关Python模块的文档。只需在系统命令提示符输入"pydoc 主题"即可。
 python -m pydoc -p 1234

 
posted @ 2019-12-21 16:40  zhouhaiwu  阅读(324)  评论(0编辑  收藏  举报