拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Python函数不是工具 是能赋值能返回的活对象

许许多多的人去学习 , 函数竟然就一直停留在「def 写上一段 、括号调整一番」这样的层面。我当初也是如此这般去想的 , 一直到后来编写代码的时候老是出现奇怪的事情: 明明是在函数里面更改了一个列表 , 外面却莫名的同样出现变化? 明明是想着给函数添加一个备注内容 , 居然确确实实能够添加上去?随后才弄清楚一件事儿: 于其中, 函数根本就不是那种「固定不动毫无变化只会执行的代码」, 它实则是具有生机与活力的一个对象, 和数字、字符串、列表属于同等层次。今日便将函数的6个「未被明显察觉的身份」一次性阐释清楚, 特别是第4个, 曾使无数人陷入困境犯错。一、函数也是对象首先写个 a 等于 100 的情况, 此时 type(a) 的结果是 int然后呢要写个函数, 这个函数的 type(函数名) 居然也是个正儿八经的类型, 这个类型叫做。这也就意味着, 函数同样也是 类的一个实例对象。做个类比: 函数如同公司之中的一名正式员工, 这名员工有着一个名字, 这个名字就是函数名, 该员工还有一个工位, 此工位是内存里的一块地址, 同时这名员工还有档案, 档案中存着函数体的代码, 它与 100 相比, 在作为对象这件事上没什么区别, 它和hello 相比, 在作为对象这层面也没什么区别, 它跟 比起来, 在作为对象这个方面同样没什么区别, 它们通通都是「对象」。def welcome(): print(你好) print(type(welcome)) #留意: 观看类型之际千万不要添加括号 (), 那所注视的是「调用进而返回之值的类型」, 并非函数自身。二、函数能动态加属性类的实例能够进行 p1.age18 的操作, 函数同样办得到。你绝对有充分的条件给函数贴上标签:welcome.desc 这是一个打招呼的函数 welcome.version 1.0 print(welcome.desc, welcome.version) # 正常打印打比方, 给员工的工牌后面贴上一枚便利贴, 其上书写着「负责打招呼」, 与此同时标注「版本 1.0」。函数对象那边同样能够挂上自定义的数据, 想用的时候随时可以取用, 并且不会出现报错的情况。三、函数能赋值给变量say_hello welcome say_hello() # 输出 你好 print(say_hello.desc) # 也能拿到属性拿给员工安个绰号来进行类比, 喊那个特定称谓, 喊这个特定称谓, 他都会过来, 原因在于所指向的是同一个活生生的人。在内存当中, 仅仅是多了一个名字而已, 然而都指向同一块地址。不管你用哪一个名字去呼喊, 所做的都是同一件事情。四、可变 / 不可变参数最关键的一个重点这是最容易踩坑的地方。先看两段代码猜猜 a 最后是多少。情况一传不可变参数数字a 666 def welcome(data): print(修改前, data, id(data)) data 888 print(修改后, data, id(data)) welcome(a) print(函数调用后 a , a) # 666怎么会 a 依旧是 666 呢? 缘由在于 666 属于不可变对象, 于函数之中, data 888 乃是另外创建了一个全新的 888 对象, 和原本的 666 没有丝毫的关联, 它在函数里面怎样变动, 外面的 a 都一点也不会改变。情况二传可变参数列表a [10, 20, 30] def welcome(data): data[2] 99 print(修改后, data) welcome(a) print(函数调用后 a , a) # [10, 20, 99]这一回a竟然也发生变动啦原因在于列表属于可变对象, 当传进去时a和data所指向的是同一个列表。你对列表里的某一项做了修改, 这就相当于触动了大家共同使用的那本账, 在外面读取时, 自然而然就是修改过后的状态了。牢牢记住一句话: 传递不可变参数就如同递给别人一张复印件, 当同事去修改他手中那张时, 你的原件不会有变动传递可变参数则好似共同使用同一本通讯录, 要是同事在其中划掉并改成 99, 等你回头翻看自己这本时, 同样也改变了——这是由于原本就是同一本。在函数之中更改不可变参数不会对外部造成影响, 然而更改可变参数, 外部必定也会随之出问题。五、函数能当参数传def welcome(): print(你好) def caller(f): print(caller 函数调用了) f() # 把收到的函数调一下 caller(welcome)进行类比, 让主管B, 带着一个助手A去上班, 就是B收下了A, 到了规定时间让A去开展工作。函数当作参数, 其本质就是把活人派去成为别人的下属。后面学习回调、装饰器全依靠这一招。六、函数能当返回值def welcome(): def show_message(msg): print(你好, msg) return show_message # 把函数交出去 result welcome() # 拿到返回的函数 result(朋友) # 输出 你好 朋友 # 也可以一行连写welcome()(朋友)进行调整, 返回的是这个函数本身并非它的执行结果。你用拿来接住, 接着喊“朋友”才会真正执行。这里存在一个坑点, 那就是它是一个在内部被定义的函数, 此函数属于特定的 “局部作用域”。要是你在外部直接写上 (“朋友”) 这样的内容, 就会出现报错显示为「未定义」的情况。要是你想要使用它, 那就使用返回的相应内容, 千万别随意去翻人家放置它的地方去寻找。写在最后这6个身份串联起来是这样的: 函数当属对象范畴, 具备添加属性的能力, 能够进行赋值操作, 其参数存在可变与不可变的分类, 可作为参数使用, 还能够充当返回值。弄明白这6个要点, 后续学习闭包、装饰器、回调之时才不会感到迷茫困惑。言简意赅来讲, 将函数视作如同「一等公民」般存在, 即它与数字、字符串处于同等地位, 其所能执行的操作远比你所设想的数量众多, 要牢记那最为关键的一点, 函数并非是一成不变的代码, 而是身为一个能够进行赋值、能够予以传递、能够实现返回的灵活对象。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门