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