前言

关于对象的魔法方法我们已经讲得太多,但是对于类或函数内建的魔法属性和功能我们涉及较少,下面系统了解一下类和函数的内建属性。

查看内建属性

class Person(object):
pass def get_name():
pass if __name__ == "__main__":
person = Person()
print(dir(get_name))
print(dir(Person))
print(dir(person))
# 结果
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

比较一下发现类和它的实例内建的属性和方法是一样的,函数似乎比类的内建的属性和方法更多,分离出属性:

  • 类的内建属性有:
'__class__', '__dict__', '__doc__', '__module__', '__weakref__'
  • 函数的内建属性有:
'__annotations__', '__class__', '__closure__', '__code__', '__defaults__', '__dict__','__doc__', '__kwdefaults__', '__module__', '__name__','__qualname__',__globals__

前面我们基本介绍过来类的内建属性,现在重点针对函数的内建属性。

函数的内建属性

内建属性是不能在函数的作用域内直接使用的,因为它们没有被显性地定义,它们需要通过函数变量来调用。

  • _annotations_

记录函数的参数和返回值的类型,前提是定义时指定了类型,否则为{}.

def get(x:int, y:int) -> int:
return x + y print(get.__annotations__) # {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}
  • _class_

python万物皆对象,所以函数也是一个对象,可以看做简化版的类的实例,它的类对象就是FunctionType。

def get(x:int, y:int) -> int:
return x + y
print(get.__class__) # <class 'function'>
  • __defaults__和__kwdefaults__

__defaults__属性用来存储参数的默认值,是一个元组,如果没有默认值为None。

def get(x:int=1, y:int=3) -> int:
return x + y
print(get.__defaults__) # (1, 3)

__kwdefaults__记录强制关键字参数的默认值,字典形式,没有置为None。

def get(x:int, y:int, *, age=20):
pass
print(get.__kwdefaults__) # {'age':20} # 函数*后面的参数表示强制关键字参数,即一定要:
get(3,4,age=30)这种方式调用
  • __name__和_qualname_

__name__和__qualname__分别表示函数的名字和合法名,__name__仅仅是函数名字,而__qualname__会用点示法显示函数所在的类和模块。

  • __doc__和_module_:和类的该属性一样,__doc__记录该函数的说明,__module__表示函数定义的模块的名字。

  • _globals_:函数定义所在模块的全局命名空间的字典的引用。

  • _closure_:以包含cell的元组形式返回闭包所包含的自由变量。

def name(x=2):
c = 0
def name1(y):
return x + y + c
return name1
n = name()
print(n.__closure__)
# 结果
(<cell at 0x000001B1B201EEB8: int object at 0x00000000619760C0>,
<cell at 0x000001B1BAEFB768: int object at 0x0000000061976100>)
# 这里的自由变量指的是y和c
  • _dict_

既然函数也是对象,那么它也应该有自己的属性,默认为{}.

def get(x:int=1, y:int=3) -> int:
return x + y
get.name = 'get'
print(get.__dict__) # {'name':'get'}
  • _code_:返回已编译的函数对象,CodeType对象。

总结

  1. 以上是普通的自定义函数的内建属性,它和生成器函数、协同函数的概念是不一样的;

  2. 对于普通的业务开发来说,需要用到的内建属性一般为:__defaults__,__name__,__doc__.

参考

python进阶之函数和类内建魔法属性的更多相关文章

  1. python进阶01 面向对象、类、实例、属性封装、实例方法

    python进阶01 面向对象.类.实例.属性封装.实例方法 一.面向对象 1.什么是对象 #一切皆对象,可以简单地将“对象”理解为“某个东西” #“对象”之所以称之为对象,是因为它具有属于它自己的“ ...

  2. js面向对象自定义MyString()的构造器函数,实现内建String()属性和方法:

    js面向对象自定义MyString()的构造器函数,实现内建String()属性和方法: var s = new MyString('hello'); s.length; s[0]; // " ...

  3. Python的getattr(),setattr(),delattr(),hasattr()及类内建__getattr__应用

    @Python的getattr(),setattr(),delattr(),hasattr() 先转一篇博文,参考.最后再给出一个例子 getattr()函数是Python自省的核心函数,具体使用大体 ...

  4. Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器

    Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器 一丶关键字:global,nonlocal global 声明全局变量: ​ 1. 可以在局部作用域声明一 ...

  5. Python进阶(二)----函数参数,作用域

    Python进阶(二)----函数参数,作用域 一丶形参角度:*args,动态位置传参,**kwargs,动态关键字传参 *args: ​ 动态位置参数. 在函数定义时, * 将实参角度的位置参数聚合 ...

  6. Python进阶(一)----函数

    Python进阶(一)----函数初识 一丶函数的初识 什么函数: ​ 函数是以功能为导向.一个函数封装一个功能 函数的优点: ​ 1.减少代码的重复性, ​ 2.增强了代码的可读性 二丶函数的结构 ...

  7. 多态,封装,反射,类内置attr属性,os操作复习

    1.多态 #多态 多态是指对象如何通过他们共同的属性和动作来操作及访问,而不需要考虑他们具体的类 运行时候,多种实现 反应运行时候状态 class H2O: def __init__(self,nam ...

  8. python面向对象的多态-类相关内置函数-类内置魔法函数-迭代器协议-上下文管理-04

    多态 一种事物具备不同的形态 例如:水 --> 固态.液态.气态 多态:# 多个不同对象可以相应同一个对象,产生不同的结果 首先强调,多态不是一种特殊的语法,而是一种状态,特性(多个不同对象可以 ...

  9. Python语法基础-函数,类以及调试处理

    [TOC] 1. 函数的定义 python中函数有两种: python自带的函数 用户定义函数 返回多个值 原来返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同 ...

随机推荐

  1. css 样式 文字过长 换行处理方法

    css强制换行.强制不换行及自动换行的写法 css强制不换行 div{white-space:nowrap;} css自动换行 div{ word-wrap: break-word; word-bre ...

  2. BZOJ3157/BZOJ3516 国王奇遇记(矩阵快速幂/数学)

    由二项式定理,(m+1)k=ΣC(k,i)*mi.由此可以构造矩阵转移,将mi*ik全部塞进去即可,系数即为组合数*m.复杂度O(m3logn),因为大常数喜闻乐见的T掉了. #include< ...

  3. Navicat使用教程:获取MySQL中的行数(第1部分)

    下载Navicat Premium最新版本 Navicat Premium是一个可连接多种数据库的管理工具,它可以让你以单一程序同时连接到MySQL.Oracle及PostgreSQL数据库,让管理不 ...

  4. 《深入理解计算机系统》学习总结 Chap7

    第七章 链接 链接是将各种代码和数据部分收集起来并组合成为一个单一文件的过程,这个文件可被加载(或拷贝)到存储器并执行.链接可以执行于编译时,也就是在源代码被翻译成机器代码时:也可以执行于加载时,也就 ...

  5. POJ.1067 取石子游戏 (博弈论 威佐夫博弈)

    POJ.1067 取石子游戏 (博弈论 威佐夫博弈) 题意分析 简单的威佐夫博弈 博弈论快速入门 代码总览 #include <cstdio> #include <cmath> ...

  6. [BZOJ1878][SDOI2009] HH的项链 (树状数组)

    link 一道简单题. 不用可持久化. 对于统计颜色个数,可以看与其颜色一样的前一个位置. 设$las(i)$表示其与$i$颜色相等的上一个位置. 则对于二元组$(l,r)$,其答案为$\sum_{i ...

  7. centos详细安装redis步骤

    1. 从官网(http://redis.io)下载最新稳定版2. 使用命令解压下载的tar包:tar –zxvf redis-3.2.0.tar.gz3. 通过命令cd redis-3.2.0进入源码 ...

  8. js字符串替换(时间转换)

    转: js中字符串全部替换 废话不多说,直接发结果 在js中字符串全部替换可以用以下方法: str.replace(/需要替换的字符串/g,"新字符串") 比如: "yy ...

  9. mac 命令行大杂烩

    一.实用的 1.代替 cat 的工具:bat,支持语法高亮.同时显示行号,使用: bat xx.yyy 安装:brew install bat 2.man 命令的替代品:tldr 安装:brew in ...

  10. 交互式shell脚本对话框----whiptail指令

    当你在linux环境下setup软件的时候就会有相应的对话框让你输入.虽然我们已经习惯了这种交互的方法,但是如果有一种直观的界面来输入是不是会更加友好和方便呢,在shell脚本中你可以使用-whipt ...