Re: [问题] 函数有无返回值?

楼主: uranusjr (←這人是超級笨蛋)   2017-12-29 19:16:42
※ 引述《sagwow (不是我)》之铭言:
: 菜鸟我在学Python时,有个最大的疑惑就是:
: "为什么有些函数需要有东西去接,有些不用?"
: 另外,在学这些函数时有方法知道到底要不要用=吗?
: 还是只能看范例照做,或是看说明文件了?
推 vfgce: 这个只能背了,函数式程式设计的精神是不做inplace修改,但 12/28 07:55
→ vfgce: 结果就是内存用量大增,而传统程式则是看你怎么写,大部分 12/28 07:56
→ vfgce: 情况下为了省内存,且确定资料不需保留后面使用,就会做 12/28 07:58
→ vfgce: inplace条改,所以你只能记那些回传,那些是inplace修改... 12/28 07:59
→ vfgce: R采用函数式程式设计,所以所有函数都回传不修改原值.所以 12/28 08:01
→ vfgce: 不用特别记,传进去的东西不会被改. 而python就看程式怎么写 12/28 08:02
→ vfgce: 有些会修改传入资料,有些是不修改回传新的..只能用记的 12/28 08:03
推 henry8168: 哭哭,我写程式写很久也是有这种疑问 O_Q 12/29 09:04
推 clsmbstu: 我也是初学者 这超困扰我... 12/29 15:09
→ clsmbstu: 而且有时候明明就只是想玩一下,不想修改原物件,反而还 12/29 15:13
→ clsmbstu: 要多做一次.copy 12/29 15:13
→ clsmbstu: function vs. method对我来说也是莫名其妙 QQ 12/29 15:16
→ clsmbstu: R的method就会挂在function 再让function吃该data type 12/29 15:18
→ clsmbstu: 不会有len(list) vs. list.sort() 却没有sort(list) 12/29 15:21
推 Sunal: 有C的指标概念应该好理解吧 只是没接触过的话就是要硬记了 12/29 15:35
先说结论, 以 Python 内建函式而言, 其实哪个要怎么用很有逻辑, 只是看不看得出来
英文母语使用者应该会觉得这非常直觉, 英文不好的话也有几个简单识别方法
首先你要考虑这个函式的结果和函式附着的东西是不是类似
这边类似的意思是有点直觉上的意义
举例而言
>>> s = 'foo bar rex'
>>> s.split(' ')
这个 split 的目的是把一个 str 分成很多个
Split 附着在 str 上, 但是输出是很多个 str (实际上是 list), 这就叫不类似
所以 split 会回传一个新东西, 和 s 无关
>>> a = ['Apple', 'Banana']
>>> a.append('Citron')
这里 append 是把东西塞到 a 的最后面
被附着的是 a, 输出...就是原本那个 a, 只是最后多了一个东西, 这就是类似
所以 append 不会回传任何东西, 因为你用本来那个 a 就好
接下来是全域函式
全域函式因为没有被附着在任何东西上, 所以都得回传东西
所以 len 永远都会回传, sorted 也是同样的道理
因为理解上不同, 全域函式的名字也会和附着在东西上面的有点不一样
len # 名词, length 的缩写, len(s) 可以理解成 s 的 length
sorted # 形容词, sorted(a) 理解成 a 的 sorted (的变化)
s.split # 动词, 理解成去 split s 这个东西
a.sort # 动词, 理解成去 sort s 这个东西
其他可以自己类推
所以只要记得那个动作的对应英文词, 就可以猜函式名称
再根据函式名称与动作的意义, 去推得那个函式的使用方法
最后一个问题是, 为什么 append 是附着在 list 上, 但是 len 却是全域
这就牵涉到这个动作到底广不广泛
Append 基本上只对 list 有用, 把它放在全域太浪费了, 所以附在 list 上面
另一方面长度这个概念很多东西都有, 在每个类型上实作太麻烦, 所以直接全域[1]
[1]: 这有点算 Python 的特例, 很多现代语言是把 len 用继承的放在类型上
但是 Python 刚开始发展的时候并没有现代的继承概念, 没办法这么做
全域名称用掉就没有了, 所以 Python 也会尽量避免新增, 尽量找其他合理方案
只有像 len sorted 这些没有更好写法的才会这样用
所以有 list.append(), 但是却没有这种函式
>>> a = ['Apple', 'Banana']
>>> appended(a, 'Citron') # Does not work.
因为可以用加法取代, 反正这个运算符在 list 上也没什么其他好用法
>>> b = a + ['Citron']
>>> b
['Apple', 'Banana', 'Citron']
>>> a
['Apple', 'Banana']
其实学语言一开始都是这样, 你都不知道为什么要这样命名, 感觉就只能背
但是学了一阵之后如果你有认真思考, 就会开始发现后面的逻辑
接下来就能真的开始学会这个语言
学程式的时候重点不是背, 而是想办法知道背后的道理
只有当你懂了道理, 才能开始在面对之前没看过的问题时, 该怎么处理
当然这不是永远行得通, 有些语言或者函式库本身就是没什么道理
但幸好 Python 至少在内建函式上还是很有道理的, 所以才说很适合程式初学者
当你学会了 Python 的道理, 也就学会了找道理的方法, 就更容易学其他程设能力
也才能分辨什么东西其实没有道理, 不会傻傻的想搞懂它
作者: vfgce (小兵)   2016-12-28 07:55:00
这个只能背了,函数式程式设计的精神是不做inplace修改,但结果就是内存用量大增,而传统程式则是看你怎么写,大部分情况下为了省内存,且确定资料不需保留后面使用,就会做inplace条改,所以你只能记那些回传,那些是inplace修改...R采用函数式程式设计,所以所有函数都回传不修改原值.所以不用特别记,传进去的东西不会被改. 而python就看程式怎么写有些会修改传入资料,有些是不修改回传新的..只能用记的
作者: henry8168 (番薯猴)   2016-12-29 09:04:00
哭哭,我写程式写很久也是有这种疑问 O_Q
作者: clsmbstu   2016-12-29 15:09:00
我也是初学者 这超困扰我...而且有时候明明就只是想玩一下,不想修改原物件,反而还要多做一次.copyfunction vs. method对我来说也是莫名其妙 QQR的method就会挂在function 再让function吃该data type不会有len(list) vs. list.sort() 却没有sort(list)
作者: Sunal (SSSSSSSSSSSSSSSSSSSSSSS)   2016-12-29 15:35:00
有C的指标概念应该好理解吧 只是没接触过的话就是要硬记了
作者: clsmbstu   2017-12-29 21:18:00
谢谢你的说明!我觉得有稍微清楚一点~ :D也想请教如果想获得关于Python内建函式,或是scopingrules等知识,有什么推荐的书或线上资源/课程吗?也许作为Python的初学者无法全看懂,但我想边学边理解主要还是想慢慢了解这语言背后的逻辑,不然顶多只是会用却不知道为什么这样用
作者: mikapauli (桜花)   2017-12-29 22:31:00
python documentationIDLE > Help > Python Docs里面的Language Reference和Library Reference和Python HOWTOs
作者: pups003 (冈本)   2017-12-30 00:17:00
用久就会啦
作者: stoltzman (......)   2017-12-30 08:21:00
解释的很清楚!原来是这样看的!
作者: henry8168 (番薯猴)   2016-01-02 21:06:00
看完觉得好懂多了,推推

Links booklink

Contact Us: admin [ a t ] ucptt.com