5.45.45.4 可调用对象

除了用户定义的函数,调用运算符(即())还可以应用到其他对象上。如果想判断对象能否调用,可以使用内置的callable()函数。Python的数据模型文档列出了以下7种可调用对象。

  • 用户定义的函数
    使用def语句或lambda表达式创建

  • 内置函数
    使用C语言(CPython)实现的函数,如len或者time.strtime

  • 内置方法
    使用C语言实现的方法,如dict.get

  • 方法
    在类的定义体中定义的函数


  • 调用类时会运行类的__new__方法创建一个实例,然后运行__init__方法,初始化该实例,然后把实例返回给调用方。因为 Python 没有new运算符,所以调用类时相当于调用函数。(通常,调用类会创建那个类的实例,不过覆盖__new__方法的话,也可能出现其他行为。)

  • 类的实例
    如果类定义了__call__方法,那么它的实例可以作为函数调用。

  • 生成器函数
    使用yield关键字的函数或方法。调用生成器函数返回的是生成器对象。

python中的可调用类型有很多,因此可以通过内置函数callable()来判断对象是否可调用。

用户自定义函数 ———— 每个函数名都有一个值,该值的类型是可以被解释器识别为用户定义函数的类型

(还是用了上一节中的例子?)

>>> [callable(i) for i in (fruits, func1, 12, 'hello')]
[False, True, False, False]
>>> [callable(i) for i in (my_func, int, str)]
[True, True]

5.55.55.5 用户定义的可调用类型

import randomclass BingoCase:def __init__(self, items):self._items = list(items)random.shuffle(self._items)def pick(self):try:return self._items.pop()except IndexError:raise LookupError('pick from empty BingoCase')def __call__(self, *args, **kwargs):return self.pick()bc = BingoCase(range(4))
print(bc.pick())  # 3
print(bc())  # 0
print(callable(bc))  # True

实现__call__方法的类是创建函数类对象的简便方法。
我们把这个类型的对象当作函数来使用,相当于重载了括号运算符。

5.65.65.6 函数内省

函数对象有很多很多的属性,除了我们之前提到的__doc__还有以下常用属性:

属性 说明
doc 用于获取函数的文档说明,如果没有,则返回 None
name 获取函数的名称
module 返回函数所在的模块,如果无则返回None
defaults 以元组的形式返回函数的默认参数,如果无默认参数则返回None
dict 包含了类里可用的属性名-属性的字典;也就是可以使用类名.属性名访问的对象
class 该实例的类对象
self 仅方法可用,如果是绑定的(bound),则指向调用该方法的类(如果是类方法)或实例(如果是实例方法),否则为None

示例如下:

>>> func1.__doc__
' return n!'
>>> func1.__name__
'func1'
>>> func1.__class__
# <class 'function'>'__iter__'
>>> func1.__qualname__
'func1'
>>> func1.__module__
'__main__'
>>> func1.__code__
<code object func1 at 0x103c5c270, file "<stdin>", line 1>
>>> func1.__globals__
"""
{'__name__': '__main__',
'__doc__': None,
'__package__': None,
'__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__spec__': None,
'__annotations__': {},
'__builtins__': <module 'builtins' (built-in)>, 'func1': <function func1 at 0x103c67b70>, 'my_func': <function func1 at 0x103c67b70>, 'fruits': ['strawberry', 'apple', 'watermalon', 'lemon'],
'reverse': <function reverse at 0x10360ce18>, 'reduce': <built-in function reduce>,
'add': <built-in function add>}
"""

从定位参数到仅限关键字参数

python中有一个很好的特性就是提供了极为灵活的参数处理机制。*args, **kwargs这两个不定参数可以帮我们省去很多麻烦。

在调用函数时,使用*或者**可以展开迭代对象,从而映射到单个参数。

示例如下:

>>> def books(name, cls=None, *content, **attrs):
...     if cls is not None:
...         attrs['class'] = cls
...     if attrs:
...         attr_str = ''.join(' %s="%s"' % (attr, value)
...                            for attr, value in sorted(attrs.items()))
...     else:
...         attr_str = ''
...     if content:
...         return '\n'.join('<%s%s>%s<%s>' % (name, attr_str, c, name)
...                          for c in content)
...     else:
...         return '<%s%s />' % (name, attr_str)>>> books('br')
'<br />'
>>> books('p', 'hello')
'<p class="hello" />'
>>> books('p', div, 'hello', 'world')
'<p class="div">hello<p>\n<p class="div">world<p>'
>>> my_tag = {'name': 'img','title':'maixue','cls':'framed','src': 'sun.jpg'}
>>> books(**my_tag)
'<img class="framed" src="sun.jpg" title="maixue" />'

在my_tag前面加上了**之后,字典中的所有元素都作为单个参数传入,同名的键就会自动绑定在指定位置,余下的则被**attrs捕获。

51假期读书笔记(下)——流畅的python相关推荐

  1. 51假期读书笔记(上)——流畅的python

    今天是51假期,我开启了新的一章,✌️! 第五章 一等函数 编程语言理论家将"一等对象"定义为满足下述条件的程序实体: 在运行时创建 能赋值给变量或者数据结构中的元素 能作为参数传 ...

  2. 读书笔记:《流畅的Python》第五章 一等函数

    # 一等对象/一等函数 ''' 1.在运行时创建 2.能赋值给变量或数据结构中的元素 3.能作为函数的参数传给函数 4.能作为函数的返回值返回结果 '''# 函数对象本身时function对象的实例d ...

  3. python读书笔记2000_流畅的Python读书笔记

    特殊方法的存在是为了Python解释器调用的,你自己并不需要去调用他们,比如说my_object.len()这种写法是没有的,应该使用len(my_object).在使用len(my_object)的 ...

  4. 读书笔记:《流畅的Python》第19章 动态属性和特性

    # 第19章 动态属性和特性""" 属性(attribute):数据的属性和处理数据的方法统称属性,方法只是可调用的属性. 特性(property)除此之外,我们海可以创 ...

  5. 读书笔记:《流畅的Python》第21章 类元编程

    # 第21章 类元编程""" 类元编程指的是运行时创建或定制类的技艺1.类是一等对象,任何时候都可以使用函数新建类,而无需使用class关键字2.类装饰器也是函数,不过能 ...

  6. 读书笔记:《流畅的Python》第17章 使用future处理并发

    # 第17章 使用future处理并发""" 内容提要:concurrent.futures模块future的概念:是一种对象,表示异步执行的操作是concurrent. ...

  7. 读书笔记:《流畅的Python》第4章 文本和字节序列

    # 第四章 文本和字节序列"""内容提要:1.Unicode字符串2.二进制序列3.在二者之间转换使用的编码4.字符/码位/字节表述5.bytes/bytearray/m ...

  8. 读书笔记:《流畅的Python》第15章 上下文管理器和else块

    # 第15章 上下文管理器和else块""" 本章内容提要:with语句和上下文管理器for while try语句的else子句 """# ...

  9. 剑指offer(第二版)读书笔记以及编程题目python版答案(二)

    剑指offer(第二版)读书笔记以及编程题目python版答案(二) 题目五:青蛙跳台阶 github地址: https://github.com/ciecus/leetcode_answers/tr ...

最新文章

  1. leetcode 24: 两两交换链表中的节点
  2. 组合键 发送指定信号_Django signal 信号机制的使用
  3. 立创eda封装转cadence_立创EDA05、检查封装、生成PCB
  4. 电子版,材料获取说明
  5. andorid 查看OpenCv Mat的Debug信息
  6. Mac OS 看机起动JIRA
  7. Redis与数据库同步问题
  8. android字符串显示textview,Android编程:TextView不显示完整字符串
  9. mysql passwor authen_mysql5.7 的 user表的密码字段从 password 变成了 authentication_string
  10. php自定义建站系统,PbootCMS(开源免费PHP建站系统) V2.0.9 官方版
  11. webpack 的plugin简单实现 customize-cra
  12. centos7 yum 配置阿里云镜像
  13. Hacking JWT(JSON Web Token)
  14. Python解释器及IDLE的使用
  15. 如何合理运用美容院资源
  16. 【开源“青女四轴”,DIY小四轴】
  17. Document读取XML
  18. 中小学花都区计算机作品比赛,2010年广州市小学电脑绘画、小报制作比赛简报.doc...
  19. java中的依赖是啥意思_java – “ – ”(箭头)在gradle的依赖图中是什么意思?
  20. 1.layer弹窗在使用时,原本隐藏的div,在打开弹窗后竟然显示出来了

热门文章

  1. h5移动端安卓键盘顶起页面回落问题
  2. ML / SML 常见错误解决办法
  3. 关于烈马、将军攻击网站假墙攻击防御方案以及轮询脚本
  4. 给百度地图每个市添加颜色
  5. ios底部栏设计规范_IOS界面设计尺寸标准规范
  6. 【不就是java设计模式吗】设计模式七大原则,用代码对比方式,化抽象为具体,实打实的教会你
  7. AtCoder Grand Contest 012 E - Camel and Oases 状压dp
  8. 萤石开放平台二次开发——摄像头取流至抖音直播平台
  9. 原生html冻结表头,Table冻结表头示例代码
  10. axure中交互样式设置鼠标悬停后其他的按下选中无效_Axure交互动作