Loading

Python基础复习

这里归纳了一些自己目前不够熟悉的Python基础知识/特性

切片

  • 官方文档 - slice

  • Python可切片对象的索引方式:

  • 切片操作基本表达式:object[start_index:end_index:step]

    • step:正负数均可,其绝对值大小决定了切取数据时的‘‘步长”,而正负号决定了“切取方向”,正表示“从左往右”取值,负表示“从右往左”取值。当step省略时,默认为1,即从左往右以增量1取值。
    • start_index:表示起始索引(包含该索引本身);该参数省略时,表示从对象“端点”开始取值,至于是从“起点”还是从“终点”开始,则由step参数的正负决定,step为正从“起点”开始,为负从“终点”开始。
    • end_index:表示终止索引(不包含该索引本身);该参数省略时,表示一直取到数据“端点”,至于是到“起点”还是到“终点”,同样由step参数的正负决定,step为正时直到“终点”,为负时直到“起点”。
  • 切片返回目标对象的浅拷贝

迭代

  • 使用for k, v in d.items()可以同时迭代dict中的key和value:

  • 使用enumerate()可以同时迭代元组的索引和元素:

>>> for i, value in enumerate(['A', 'B', 'C']):
...     print(i, value)
...
0 A
1 B
2 C

生成器

廖雪峰python - 生成器

迭代器

  • 可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
  • 可以使用isinstance()判断一个对象是否是Iterator对象

高阶函数

map/reduce

  • map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回
  • reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

filter

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

sorted

  • Python内置的sorted()函数可以对list进行排序
  • sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:
>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
  • key指定的函数将作用于list的每一个元素上,并根据key函数返回的结果进行排序。

偏函数

  • functools.partial()可以用来创建一个偏函数
  • python中偏函数的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
>>> int('12345', base=8)
5349
>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64

OOP访问限制

  • 实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问:
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))

多态

  • 当子类和父类存在相同名称的方法时,子类的同名方法将覆盖父类的对应方法

调试

  • 最简单的调试方法是使用print()来查看变量信息
    • print()的缺点是它将产生大量垃圾代码
  • 所以,更进一步的方法是使用断言(assert)来替代print():
    • assert n != 0, 'n is zero!'
  • assert会检查后面的表达式的布尔值。如果为false,assert会抛出AssertionError
  • 最成熟的调试方式是使用logging
import logging
logging.basicConfig(level=logging.INFO)  # 配置控制台日志输出级别

logging.info("xxx")

单元测试

Python高级OOP

slots

  • Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:
class Student(object):
    __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
>>> s = Student() # 创建新的实例
>>> s.name = 'Michael' # 绑定属性'name'
>>> s.age = 25 # 绑定属性'age'
>>> s.score = 99 # 绑定属性'score'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'score'

@property

  • 为了实现既能检查参数,又可以用类似属性这样简单的方式来访问类的变量,Python提供了内置的@property装饰器来实现方法到属性的转换:
class Student(object):

    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value
  • 把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值
  • 只定义getter方法,不定义setter方法就是一个只读属性

多继承

  • 多继承又被称作MixIn
  • MixIn的目的就是给一个类增加多个功能,这样,在设计类的时候,我们优先考虑通过多重继承来组合多个MixIn的功能,而不是设计多层次的复杂的继承关系
  • Python自带的很多库也使用了MixIn。
    • Python自带了TCPServer和UDPServer这两类网络服务,而要同时服务多个用户就必须使用多进程或多线程模型,这两种模型由ForkingMixIn和ThreadingMixIn提供。通过组合,我们就可以创造出合适的服务来
    • 比如,编写一个多进程模式的TCP服务,定义如下:
class MyTCPServer(TCPServer, ForkingMixIn):
    pass
- 编写一个多线程模式的UDP服务,定义如下:
class MyUDPServer(UDPServer, ThreadingMixIn):
    pass

定制类(魔法方法)

  • 看到类似__slots__这种形如__xxx__的变量或者函数名就要注意,这些在Python中是有特殊用途的
  • 类似的方法还有:
    • len()方法能让class作用于len()函数
    • str()方法用于变更实例的print()内容
    • repr()方法用于变更实例在控制台的输出结果
    • iter()方法可以让实例变成迭代器
    • 更多定制方法见:Python Doc - special method names

枚举类

元类

  • Python - type()
  • 使用type,我们可以在程序中动态地创建类型,包括类,对象和函数等
  • 元类的一个典型应用场景是ORM:
    • ORM全称“Object Relational Mapping”,即对象-关系映射,就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表,这样,写代码更简单,不用直接操作SQL语句
    • 要编写一个ORM框架,所有的类都只能动态定义,因为只有使用者才能根据表的结构定义出对应的类来

posted @ 2019-07-08 15:54  云野Winfield  阅读(202)  评论(0编辑  收藏  举报