Python3基础教程之高级特性1

1、切片(Slice)操作符

示例一:

# 取L前三个元素之笨方法
L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
print([L[0], L[1], L[2]])
# 聪明方法1
r = []
n = 3
for i in range(n):
    r.append(L[i])
print(r)
# 聪明方法2:L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3
print(L[0:3])           # 0可以省略不写
print(L[-2:])           # 包括最后一个元素
print(L[-2:-1])         # 不包括最后一个元素

示例二: 

# 用list创建一个 0-99 的数列
L = list(range(100))    # 包括0不包括100
print(L)
# 两者不同,后10个数,后10个数去除最后一个数
print(L[-10:])
print(L[-10:-1])
# 前11-20个数
L[10:20]
# 前 10 个数,每两个取一个
L[:10:2]
# 所有数,从第一个数开始,每 5 个取一个:
print(L[::5])
# 只写[:]就可以原样复制一个 list
L[:]
# tuple 也可以用切片操作,只是操作的结果仍是 tuple
(0, 1, 2, 3, 4, 5)[:3]
# 字符串也可以用切片操作,只是操作结果仍是字符串
'ABCDEFG'[:3]       

2、迭代

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

# 在 Python 中,迭代是通过 for ... in 来完成的
d = {'a': 1, 'b': 2, 'c': 3}    # dict
for key in d:
    print(key)
# 迭代对象为字符串
for ch in 'ABC':
    print(ch)

2.2 通过 collections.abc 模块的 Iterable 类型判断一个对象是否可迭代

from collections.abc import Iterable
print(isinstance('abc', Iterable)) # str 是否可迭代
print(isinstance([1,2,3], Iterable)) # list 是否可迭代
print(isinstance(123, Iterable)) # 整数是否可迭代
 # enumerate 函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:
for i, value in enumerate(['A', 'B', 'C']):
    print(i, value)
# 同时引用了两个变量
for x, y in [(1, 1), (2, 4), (3, 9)]:
    print(x, y)

3、列表生成式

# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
a=list(range(1, 11))
print(a)
# 生成 [1x1, 2x2, 3x3, ..., 10x10]
# 方法一:
L = []
for x in range(1, 11):
    L.append(x * x)
print(L)        # 循环里输出和循环外输出
# 方法二
a=[x * x for x in range(1, 11)]
print(a)
# for 循环后面还可以加上 if 判断
a=[x * x for x in range(1, 11) if x % 2 == 0]
print(a)
# 使用两层循环,可以生成全排列
a=[m + n for m in 'ABC' for n in 'XYZ']
print(a)
# 列出当前目录下的所有文件和目录名
import os
print([d for d in os.listdir('.')])
# for 循环其实可以同时使用两个甚至多个变量,比如dict的items()可以同时迭代 key 和 value:
d = {'x': 'A', 'y': 'B', 'z': 'C' }
for k, v in d.items():
    print(k, '=', v)
# 列表生成式也可以使用两个变量来生成 list
d = {'x': 'A', 'y': 'B', 'z': 'C' }
print([k + '=' + v for k, v in d.items()])
# 把一个 list 中所有的字符串变成小写
L = ['Hello', 'World', 'IBM', 'Apple']
print([s.lower() for s in L])

4、生成器

在 Python 中,这种一边循环一边计算的机制,称为生成器:generator。

# 把一个列表生成式的 [] 改成 () ,就创建了一个 generator
L = [x * x for x in range(10)]  # list
g = (x * x for x in range(10))  # generator
print(L)
print(g)
# 通过 next() 函数获得 generator 的下一个返回值
print(next(g))
print(next(g))
print(next(g))
# 方法二:使用for循环
g = (x * x for x in range(10))
for n in g:
    print(n)
# 用函数把它打印出斐波拉契数列用列表生成式写不出来
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        print(b)
        a, b = b, a + b
        n = n + 1
    return 'done'
print(fib(6))
# 要把 fib 函数变成generator,只需要把 print(b) 改为 yield b 就可以了
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'
print(fib(6))
# 使用 for 循环来迭代,获取下一个返回值
for n in fib(6):
    print(n)
#  得到generator的return语句的返回值
g = fib(6)
while True:
    try:
        x = next(g)
        print('g:', x)
    except StopIteration as e:
        print('Generator return value:', e.value)
        break

5、迭代器

5.1

可以直接作用于 for 循环的对象统称为可迭代对象: Iterable 。

# 使用 isinstance() 判断一个对象是否是 Iterable 对象
from collections.abc  import Iterable
print(isinstance([], Iterable))
print(isinstance({}, Iterable))
print(isinstance('abc', Iterable))
print(isinstance((x for x in range(10)), Iterable))
print(isinstance(100, Iterable))

5.2 可以被 next() 函数调用并不断返回下一个值的对象称为迭代器:Iterator 。

from collections.abc import Iterator
a=isinstance((x for x in range(10)), Iterator)
a=isinstance([], Iterator)
a=isinstance({}, Iterator)
a=isinstance('abc', Iterator)
print(a)
# 把 list 、 dict 、 str 等 Iterable 变成 Iterator 可以使用 iter() 函数
a=isinstance(iter([]), Iterator)
a=isinstance(iter('abc'), Iterator)
print(a)

6、高阶函数

6.1 变量可以指向函数

# 函数本身也可以赋值给变量
f = abs
print(f(-10))

6.2 函数名也是变量

# 要恢复abs函数,请重启Python交互环境
abs = 10
abs(-10)    # 输出有误

6.3 传入函数

一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

# 示例一
def add(x, y, f):
    return f(x) + f(y)
a=add(-5, 6, abs)
print(a)

7、Python内建函数

7.1 map/reduce

 map() 函数接收两个参数,一个是函数,一个是 Iterable ,map 将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator 返回。

def f(x):
    return x * x
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print(list(r))
# 把这个list 所有数字转为字符串
print(list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])))
# 方法二
L = []
for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
    L.append(f(n))
print(L)

reduce 把一个函数作用在一个序列 [x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce 把结果继续和序列的下一个元素做累积计算。

from functools import reduce
def add(x, y):
    return x + y
a=reduce(add, [1, 3, 5, 7, 9])
print(a)
# 把str转换为int的函数
from functools import reduce
def str2int(s):
    def fn(x, y):
        return x * 10 + y
    def char2num(s):
        return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6,'7': 7, '8': 8, '9': 9}[s]
    return reduce(fn, map(char2num, s))
a=str2int('13579')
print(a)

7.2 filter

 filter() 也接收一个函数和一个序列。和 map() 不同的时,filter() 把传入的函数依次作用于每个元素,然后根据返回值是 True 还是 False 决定保留还是丢弃该元素。 

 filter() 函数返回的是一个 Iterator ,也就是一个惰性序列,所以要强迫 filter() 完成计算结果,需要用 list() 函数获得所有结果并返
回 list。

# 在一个list中,删掉偶数,只保留奇数
def is_odd(n):
    return n % 2 == 1
a=list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
print(a)
# 把一个序列中的空字符串删掉
def not_empty(s):
    return s and s.strip()
a=list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))
# 用 用 filter 
def _odd_iter():    # 这是一个生成器,并且是一个无限序列
    n = 1
    while True:
        n = n + 2
        yield n
def _not_divisible(n):  # 定义一个筛选函数
    return lambda x: x % n > 0
def primes():   # 这个生成器先返回第一个素数2,然后,利用filter()不断产生筛选后的新的序列。
    yield 2
    it = _odd_iter() # 初始序列
    while True:
        n = next(it) # 返回序列的第一个数
        yield n
        it = filter(_not_divisible(n), it) # 构造新序列
# 打印 1000 以内的素数:
for n in primes():
    if n < 1000:
        print(n)
    else:
        break

7.3 排序算法(sorted)

# 对 list 进行排序
a=sorted([36, 5, -12, 9, -21])
print(a)
# 按绝对值大小排序
a=sorted([36, 5, -12, 9, -21], key=abs)
print(a)
# 对字符串排序,是按照ASCII的大小比较的
a=sorted(['bob', 'about', 'Zoo', 'Credit'])
print(a)
# 忽略大小写的排序
a=sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
print(a)
# 反向排序
a=sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower,reverse=True)
print(a)

7.4 返回函数:函数作为返回值

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

# 求和函数
def calc_sum(*args):
    ax = 0
    for n in args:
        ax = ax + n
    return ax
a=calc_sum(1, 2, 3)
print(a)
# 不返回求和的结果,而是返回求和的函数
def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum
f = lazy_sum(1, 3, 5, 7, 9)
print(f())

7.5 闭包

# 返回函数不要引用任何循环变量,或者后续会发生变化的变量。
def count():
    fs = []
    for i in range(1, 4):
        def f():
            return i*i
        fs.append(f)
    return fs
f1, f2, f3 = count()
print(f1())
print(f2())
print(f3())
# 解决办法:创建一个函数,用该函数的参数绑定循环变量当前的值
def count():
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i)) # f(i)立刻被执行,因此 i 的当前值被传入 f()
    return fs
f1, f2, f3 = count()
print(f1())
print(f2())
print(f3())

7.6 匿名函数

关键字 lambda 表示匿名函数,冒号前面的 x 表示函数参数。

# 直接传入匿名函数
a=list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
print(a)
# 把匿名函数赋值给一个变量
f = lambda x: x * x
print(f(5))

7.7 装饰器

在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

# 函数名
def now():
    print('2015-3-25')
f=now
print(f())
print(now.__name__)
print(f.__name__)
# 定义一个能打印日志的 decorator
def log(func):
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper
@log
def now():
    print('2015-3-25')
print(now())
# 自定义 log 的文本
def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator
@log('execute')
def now():
    print('2015-3-25')
print(now())
# 把原始函数的__name__等属性复制到wrapper()函数中
# 方法一:
import functools
def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kw):
        print('call %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper
@log
def now():
    print('2015-3-25')
print(now())
print(now.__name__)
# 方法二:针对带参数的 decorator
import functools
def log(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator
@log
def now():
    print('2015-3-25')
print(now.__name__)

7.8 偏函数

 functools.partial 的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数
会更简单。(也可以在函数调用时传入其他值)

#  int(x, base=N) N 进制的转换
# 创建一个新的函数 int2 :
import functools
int2 = functools.partial(int, base=2)
print(int2('1000000'))
# 把10作为*args的一部分自动加到左边
max2 = functools.partial(max, 10)
print(max2(5, 6, 7))

8、模块

在 Python 中,一个.py 文件就称之为一个模块(Module)。(尽量不要与内置函数名字冲突)

通过包(Package)来组织模块,避免冲突。引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别
人冲突。现在, abc.py 模块的名字就变成了 mycompany.abc ,类似的, xyz.py的模块名变成了 mycompany.xyz 。mycompany为包文件名字。

 8.1 Python 模块的标准文件模板:

#!/usr/bin/env python3          # 让这个hello.py文件直接在Unix/Linux/Mac上运行
# -*- coding: utf-8 -*-         # 表示.py文件本身使用标准UTF-8编码

' a test module '               # 任何模块代码的第一个字符串都被视为模块的文档注释

__author__ = 'Michael Liao'     # 用 __author__ 变量把作者写进去

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()
print(__author__)
# 运行 python hello3.py 获得的 sys.argv 就是 ['hello.py'] ;
import sys
print( sys.argv)

 8.2 安装第三方模块

# 找个图片生成缩略图
from PIL import Image
im = Image.open('test.png')
print(im.format, im.size, im.mode)
im.thumbnail((200, 100))
im.save('thumb.jpg', 'JPEG')    # 无法保存

 8.3 模块搜索路径

# 搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中
import sys
print(sys.path)
# 一是直接修改 sys.path,添加要搜索的目录
import sys
sys.path.append('/Users/michael/my_py_scripts')
# 第二种方法是设置环境变量 PYTHONPATH ,该环境变量的内容会被自动添加到模块搜索路径中。

9、作用域

正常的函数和变量名是公开的(public),类似 __xxx__ 这样的变量是特殊变量。类似 _xxx 和 __xxx 这样的函数或变量就是非公开的(private)。

# 外部不需要引用的函数全部定义成 private,只有外部需要引用的函数才定义为 public。
def _private_1(name):
    return 'Hello, %s' % name
def _private_2(name):
    return 'Hi, %s' % name
def greeting(name):
    if len(name) > 3:
        return _private_1(name)
    else:
        return _private_2(name)

外部不需要引用的函数全部定义成 private,只有外部需要引用的函数才定义为 public。

def _private_1(name):
    return 'Hello, %s' % name
def _private_2(name):
    return 'Hi, %s' % name
def greeting(name):
    if len(name) > 3:
        return _private_1(name)
    else:
        return _private_2(name)
print(greeting('michael'))

 10、面向对象编程

# 面向过程的程序可以用一个 dict 表示
std1 = { 'name': 'Michael', 'score': 98 }
std2 = { 'name': 'Bob', 'score': 81 }
def print_score(std):
    print('%s: %s' % (std['name'], std['score']))
print(std1)
# 
class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score
    def print_score(self):
        print('%s: %s' % (self.name, self.score))
# 
bart = Student('Bart Simpson', 59)
lisa = Student('Lisa Simpson', 87)
bart.print_score()
lisa.print_score()

11、类和实例

# 定义类是通过 class 关键字
class Student(object):      # class 后面紧接着是类名
    pass
# 创建实例是通过类名+()实现的
bart = Student()
print(bart)         # 内存地址
print(Student)      #  Student 本身则是一个类
# 给实例 bart 绑定一个 name属性
bart.name = 'Bart Simpson'
print(bart.name)
# 把name,score等属性绑上去
class Student(object):
    def __init__(self, name, score):    #__init__ 方法的第一个参数永远是 self ,表示创建的实例本身
        self.name = name
        self.score = score
bart = Student('Bart Simpson', 59)
print(bart.name)
print(bart.score)

11.1 数据封装

# 打印一个学生的成绩
class Student(object):
    def __init__(self, name, score):    #__init__ 方法的第一个参数永远是 self ,表示创建的实例本身
        self.name = name
        self.score = score
bart = Student('Bart Simpson', 59)
def print_score(std):
    print('%s: %s' % (std.name, std.score))
print_score(bart)
# 
class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score
    def print_score(self):
        print('%s: %s' % (self.name, self.score))

12 访问限制

让内部属性不被外部访问

# 把属性的名称前加上两个下划线__变成了一个私有变量(private)
class Student(object):
    def __init__(self, name, score):
        elf.__name = name
        self.__score = score
    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))
bart = Student('Bart Simpson', 98)
print(bart.__name)
#  Student 类增加get_name 和 get_score 这样的方法
class Student(object):
...
    def get_name(self):
        return self.__name
    def get_score(self):
        return self.__score
# 允许外部代码修改 score
class Student(object):
...
    def set_score(self, score):
        self.__score = score
# 示例
class Student(object):

    def __init__(self, name, score):
        self.__name = name
        self.__score = score

    def get_name(self):
        return self.__name

    def get_score(self):
        return self.__score

    def set_score(self, score):
        if 0 <= score <= 100:
            self.__score = score
        else:
            raise ValueError('bad score')

    def get_grade(self):
        if self.__score >= 90:
            return 'A'
        elif self.__score >= 60:
            return 'B'
        else:
            return 'C'

bart = Student('Bart Simpson', 59)
print('bart.get_name() =', bart.get_name())
bart.set_score(60)
print('bart.get_score() =', bart.get_score())

print('DO NOT use bart._Student__name:', bart._Student__name)

13、继承和多态

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

# 编写了一个名为 Animal 的 class
class Animal(object):
    def run(self):
        print('Animal is running...')
# 从 Animal 类继承
class Dog(Animal):
    pass
class Cat(Animal):
    pass
dog = Dog()
dog.run()
cat = Cat()
cat.run()
# 对子类增加一些方法
class Dog(Animal):
    def run(self):
        print('Dog is running...')
    def eat(self):
        print('Eating meat...')
dog = Dog()
dog.run()
dog.eat()
# 对Dog 和 Cat 类改进
class Dog(Animal):
    def run(self):
        print('Dog is running...')
class Cat(Animal):
    def run(self):
        print('Cat is running...')
dog = Dog()
dog.run()
cat = Cat()
cat.run()
# 判断一个变量是否是某个类型可以用 isinstance() 判断
a = list()
b = Animal()
c = Dog()
a=isinstance(a, list)
print(a)
a=isinstance(b, Animal)
print(a)
a=isinstance(c, Dog)
print(a)
a=isinstance(c, Animal)
print(a)
# 反过来就不行
b = Animal()
a=isinstance(b, Dog)
print(a)            # false
# 理解多态的好处
def run_twice(animal):
    animal.run()
    animal.run()
run_twice(Animal())
run_twice(Dog())
run_twice(Cat())
# 再定义一个 Tortoise类型
class Tortoise(Animal):
    def run(self):
        print('Tortoise is running slowly...')
run_twice(Tortoise())

静态语言:传入的对象必须是 Animal 类型或者它的子类 vs  动态语言:只需要保证传入的对象有一个 run() 方法就可以了

14、获取对象信息

# 判断对象类型
a=type(123)
print(a)
a=type('str')
print(a)
a=type(None)
print(a)
# 一个变量指向函数或者类
a=type(abs)
print(a)
# 比较两个变量的 type 类型是否相同
print(type(123)==type(456))
print(type(123)==int)
print(type('abc')==type('123'))
print(type('abc')==str)
print(type('abc')==type(123))
# 判断一个对象是否是函数
import types
def fn():
    pass
print(type(fn)==types.FunctionType)
print(type(abs)==types.BuiltinFunctionType)
print(type(lambda x: x)==types.LambdaType)
print(type((x for x in range(10)))==types.GeneratorType)
# 能用 type() 判断的基本类型也可以用 isinstance() 判断
print(isinstance('a', str))

# 判断一个变量是否是某些类型中的一种
print(isinstance([1, 2, 3], (list, tuple)))
print(isinstance((1, 2, 3), (list, tuple)))

使用 dir()获得一个对象的所有属性和方法

# 获得一个 str 对象的所有属性和方法
print(dir('ABC'))
# 等价代码
print(len('ABC'))
print('ABC'.__len__())
#  lower() 返回小写的字符串
print('ABC'.lower())
# 配合 getattr() 、 setattr() 以及hasattr() ,我们可以直接操作一个对象的状态
class MyObject(object):
    def __init__(self):
        self.x = 9
    def power(self):
        return self.x * self.x
obj = MyObject()
# 有属性'x'吗?
print(hasattr(obj, 'x'))
# 有属性'y'吗?
print(hasattr(obj, 'y'))
# 设置一个属性'y'
print(setattr(obj, 'y', 19))
# 有属性'y'吗?
print(hasattr(obj, 'y'))
# 获取属性'y'
print(getattr(obj, 'y'))
# 获取属性'y'
print(obj.y)
# 获取属性'z',如果不存在,返回默认值404
print(getattr(obj, 'z', 404))
# 有属性'power'吗?
print(hasattr(obj, 'power'))
# 获取属性'power'
print(getattr(obj, 'power'))
# 获取属性'power'并赋值到变量 fn
fn = getattr(obj, 'power')
# fn 指向 obj.power
print(fn)
print(fn())

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第1 章 快速上手:基础知识 ........................ 1 1.1 交互式解释器 ........................................... 1 1.2 算法是什么 ............................................... 2 1.3 数和表达式 ............................................... 3 1.4 变量 .......................................................... 5 1.5 语句 .......................................................... 5 1.6 获取用户输入 ........................................... 7 1.7 函数 .......................................................... 8 1.8 模块 .......................................................... 8 1.8.1 cmath 和复数 ................................. 9 1.8.2 回到未来 ...................................... 10 1.9 保存并执行程序 ...................................... 10 1.9.1 从命令提示符运行Python 脚本 .............................................. 12 1.9.2 让脚本像普通程序一样 ............... 12 1.9.3 注释 .............................................. 13 1.10 字符串 .................................................... 13 1.10.1 单引号字符串以及对引号 转义 .......................................... 14 1.10.2 拼接字符串 .............................. 15 1.10.3 字符串表示str 和repr ............ 15 1.10.4 长字符串、原始字符串和 字节 .......................................... 16 1.11 小结 ....................................................... 21 1.11.1 本章介绍的新函数 ................... 21 1.11.2 预告 .......................................... 22

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值