在 Python 里,万物都有 id
print(id(42)) # 整数也是对象
print(id("hello")) # 字符串也是
print(id([1, 2, 3])) # 列表也是
print(id(print)) # 函数也是
print(id(int)) # 类型本身也是
每个对象都有:
- 身份(id,内存地址)
- 类型(type)
- 值
类是对象
class Player: pass
print(type(Player)) # <class 'type'>
print(Player.__class__) # <class 'type'>
类的"类"是 type——这就是元类的伏笔。
函数是对象
def greet(name):
return f"hi {name}"
print(type(greet)) # <class 'function'>
# 可以赋给变量
f = greet
print(f("WadeLy"))
# 可以放进列表
funcs = [greet, str.upper, len]
for f in funcs:
print(f("hello"))
# 可以当参数传
def call_twice(fn, x):
return fn(x), fn(x)
call_twice(greet, "WadeLy")
这条特性是装饰器、回调、函数式编程的基础。
一切对象都有属性
def greet(name):
"""打招呼"""
return f"hi {name}"
print(greet.__name__) # 'greet'
print(greet.__doc__) # '打招呼'
print(greet.__module__)
greet.tag = "social" # 函数也能加属性!
看一个对象有什么
print(dir("hello")) # 字符串的所有方法和属性
print(vars(some_obj)) # 对象的 __dict__(实例属性)
help(str) # 文档
实战意义
理解"一切皆对象"后,下面这些就不再神奇:
- 用
dict[func] = "标记"给函数打 tag - 把函数列表放进
dict实现"命令分发" - 装饰器 = 接收函数返回函数
- 类装饰器 = 接收类返回类
# 命令分发模式
def cmd_add(args): ...
def cmd_list(args): ...
def cmd_done(args): ...
COMMANDS = {
"add": cmd_add,
"list": cmd_list,
"done": cmd_done,
}
cmd, *args = sys.argv[1:]
COMMANDS[cmd](args)
下一篇讲函数式工具:map / filter / reduce / lambda。