Python在设计之初,就确立了充分相信用户的原则。轻封装和类型安全机制,用户自己保证其使用正确性。代表性的设计就是class不提供private关键字;无法定义常量;函数参数无类型,只有运行时类型检查;几乎所有定义都可以动态修改。这些设定与传统静态语言相比,牺牲安全性换取了异常强大而便捷的动态特性,使得Python非常适合进行小规模程序的快速开发、策略的高频迭代。
长期习惯了C/C++系的静态语言后,切换到Python中往往仍习惯使用静态办法解决问题,而不能充分利用Python的动态特性。这往往使得代码变得不必要地长且难以理解。
希望在进阶Python的过程中,逐步掌握更加高级、简捷的语言特性,将更多的精力放到解决问题当中去。

继承和多态

对于Python而言,由于只有运行时类型检查,不需要用abstract class 或interface实现多态,直接将不同对象扔到一个list里依次调用即可,不存在的方法在运行时报错。
该编程风格称为duck-typing

用于符号表、数据库、场景管理十分方便

函数对象

在Python中,以函数作为对象进行传递是很普遍的做法,典型应用例如:

  • 数值优化中作为目标函数
  • 回调函数

Python对可变参数列表提供了完善的支持

import inspect

inspect.getargspec(foo)
#返回ArgSpec(args, varargs, keywords, defaults) 其中default是最后n个默认值

#此外还有
inspect.getfullargspec(func)
inspect.currentframe()  #当前执行上下文
inspect.stack()     #栈

用字符串创建对应名字的类对象

class ButtonFactory():
    def create_button(self, typ):
        targetclass = typ.capitalize()
        return globals()[targetclass]()

使用方法

button_obj = ButtonFactory()
button_obj.create_button('button').

类方法的动态指定

class  Fruit(object):
    pass

def add(self):
    print("add")

def update(self):
    print("update")

if __name__ == "__main__"
    Fruit.grow = add
    fruit = Fruit()
    fruit.grow()
    Fruit.grow = update    #注意此处没有新建对象,只更改了类
    fruit.grow()

输出

add
update

变量的动态类型转换

list中可以混合存放各种类型对象
numpy.array中的


动态化属性和方法的调用

  • __getattr__ 当调用不存在的属性时,如果存在__getattr__方法,就会调用来尝试获得属性
  • __call__ 使实例本身变成可调用的。
class Chain(object):

    def __init__(self, path=''):
        self._path = path

    def __getattr__(self, path):
        return Chain('%s/%s' % (self._path, path))

    def __str__(self):
        return self._path

    def __call__(self, attr):
        return Chain('%s/%s' % (self._path, attr))

直接使用 Chain().schools.status.users 就可以得到格式化字符串 schools/status/users
若需要 /schools/users/ID/report,其中ID是一个参数,则可以利用__call__将对象变成可调用的 Chain().schools.users(ID).report