Scala中Method方法和Functionjs中函数和方法的区别的区别

相关文章推荐
本文原文出处: http://blog.csdn.net/bluishglc/article/details/ 严禁任何形式的转载,否则将委托CSDN官方维护权益!从使用case语句构造匿名函数谈起在...
在Scala中函数和方法有什么区别
方法可以作为一个表达式的一部分出现(调用函数并传参),但是方法(带参方法)不能作为最终的表达式,
但是函数可以作为最终的表达式出现:
Scala 模式匹配之Type、Array、List和Tuple介绍。
第46讲:ClassTag 、Manifest、ClassManifest、TypeTag代码实战及其在Spark中的应用源码解析学习笔记
应用最多的是classTag,其次是TypeTag.
Scala里高阶函数的组合,高度的代码重用
偏函数的组合
译者注:原文出处/blog//the-neophytes-guide-to-scala-part-4-pattern-match...
Scala gives a lot of flexibility in defining anonymous functions, and that might lead to a confussio...
首先我们需要实现的是,数据在那里不动,有一个方法,可以接受方法作为参数,根据不同的方法,实现不同的结果返回.
类似于scala中的函数作为参数进行传递.
首先我们需要一个容器类,进行方法的定义:
为了方便且内容显示更清楚,这里大部分都是使用scala的shell操作
他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)方法(method)和函数(function)有什么区别? - 文章 - 伯乐在线
& 方法(method)和函数(function)有什么区别?
【感谢 的热心翻译。如果其他朋友也有不错的原创或译文,可以尝试。】
“我用了很久的Applescript,但在shell脚本设计方面还是个新手。为了提高脚本性能,我想要多了解一些常用的脚本语言,譬如Javascript或Python。
有些概念我一直很困惑,譬如“面向对象”、“类”和“实例化”。
希望有人能用简洁的话语帮我解释下方法(method)和函数(function)的区别。在google上找到的那些答案对我来说太难理解了。
这个问题还是
在 2008 年 9 月 30 日在 StackOverflow 上提问的。
下面先来看看被选为最佳答案的回复(来自
函数是一段代码,通过名字来进行调用。它能将一些数据(参数)传递进去进行处理,然后返回一些数据(返回值),也可以没有返回值。
所有传递给函数的数据都是显式传递的。
方法也是一段代码,也通过名字来进行调用,但它跟一个对象相关联。方法和函数大致上是相同的,但有两个主要的不同之处:
方法中的数据是隐式传递的;
方法可以操作类内部的数据(请记住,对象是类的实例化–类定义了一个数据类型,而对象是该数据类型的一个实例化)
以上只是简略的解释,忽略了作用域之类的问题。
答案的补充:
对于 1),你应当再加上“ 方法在 C++ 中是被称为成员函数”。因此,在 C++ 中的“方法”和“函数”的区别,就是“成员函数”和“函数”的区别。此外,诸如 Java 一类的编程语言只有“方法”。所以这时候就是“静态方法”和“方法”直接的区别。
对于2),你应当补上方法可以操作已在类中声明的私有实例(成员)数据。其他代码都可以访问公共实例数据。
方法和对象相关;
函数和对象无关。
Java中只有方法,C中只有函数,而C++里取决于是否在类中。
关于“方法”和“函数”之间的区别,欢迎其他朋友在评论补充自己观点。
关于作者:
可能感兴趣的话题
函数是这类事情是怎么干的,方法是某种人是如何干这类事情的!
关于伯乐在线博客
在这个信息爆炸的时代,人们已然被大量、快速并且简短的信息所包围。然而,我们相信:过多“快餐”式的阅读只会令人“虚胖”,缺乏实质的内涵。伯乐在线内容团队正试图以我们微薄的力量,把优秀的原创文章和译文分享给读者,为“快餐”添加一些“营养”元素。
新浪微博:
推荐微信号
(加好友请注明来意)
– 好的话题、有启发的回复、值得信赖的圈子
– 分享和发现有价值的内容与观点
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 翻译传播优秀的外文文章
– 国内外的精选文章
– UI,网页,交互和用户体验
– 专注iOS技术分享
– 专注Android技术分享
– JavaScript, HTML5, CSS
– 专注Java技术分享
– 专注Python技术分享
& 2017 伯乐在线标签:至少1个,最多5个
函数与方法的区别
随着我们越来越频繁使用Python, 我们难免会接触到类, 接触到类属性和方法.但是很多新手包括我, 不知道方法 和 函数 的区别,这次简单来讨论下, 如果有哪里认识不正确, 希望大神提点指教!先来看两个定义吧:
function(函数) —— A series of statements which returns some value toa caller. It can also be passed zero or more arguments which may beused in the execution of the body.method(方法) —— A function which is defined inside a class body. Ifcalled as an attribute of an instance of that class, the methodwill get the instance object as its first argument (which isusually called self).
从上面可以看出, 别的编程语言一样, Function也是包含一个函数头和一个函数体, 也同样支持0到n个形参,而Method则是在function的基础上, 多了一层类的关系, 正因为这一层类, 所以区分了 function 和 method.而这个过程是通过 PyMethod_New实现的
PyObject *
PyMethod_New(PyObject *func, PyObject *self, PyObject *klass)
register PyMethodObject *
// 定义方法结构体
im = free_
if (im != NULL) {
free_list = (PyMethodObject *)(im-&im_self);
PyObject_INIT(im, &PyMethod_Type);
numfree--;
im = PyObject_GC_New(PyMethodObject, &PyMethod_Type);
if (im == NULL)
return NULL;
im-&im_weakreflist = NULL;
Py_INCREF(func);
/* 往下开始通过 func 配置 method*/
im-&im_func =
Py_XINCREF(self);
im-&im_self =
Py_XINCREF(klass);
im-&im_class =
_PyObject_GC_TRACK(im);
return (PyObject *)
所以本质上, 函数和方法的区别是: 函数是属于 FunctionObject, 而 方法是属 PyMethodObject简单来看下代码:
def aa(d, na=None, *kasd, **kassd):
class A(object):
def f(self):
print '#### 各自方法描述 ####'
print '## 函数
print '## 类方法
print '## 实例方法 %s' % a.f
#### 各自方法描述 ####
&function aa at 0xAB38&
&unbound method A.f&
## 实例方法 &bound method A.f of &__main__.A object at 0x3198&&
Bound Method 和 Unbound Method
method 还能再分为 Bound Method 和 Unbound Method, 他们的差别是什么呢? 差别就是 Bound method 多了一个实例绑定的过程!A.f 是 unbound method, 而 a.f 是 bound method, 从而验证了上面的描述是正确的!
看到这, 我们应该会有个问题:
方法的绑定, 是什么时候发生的? 又是怎样的发生的?
带着这个问题, 我们继续探讨.很明显, 方法的绑定, 肯定是伴随着class的实例化而发生,我们都知道, 在class里定义方法, 需要显示传入self参数, 因为这个self是代表即将被实例化的对象。我们需要dis模块来协助我们去观察这个绑定的过程:
[root@iZ23pynfq19Z ~]# cat 33.py
class A(object):
def f(self):
return 123
print A.f()
print a.f()
## 命令执行 ##
[root@iZ23pynfq19Z ~]# python -m dis 33.py
0 LOAD_CONST
3 LOAD_NAME
0 (object)
6 BUILD_TUPLE
9 LOAD_CONST
1 (&code object A at 0x7fc32f0b5030, file "33.py", line 1&)
12 MAKE_FUNCTION
15 CALL_FUNCTION
18 BUILD_CLASS
19 STORE_NAME
22 LOAD_NAME
25 CALL_FUNCTION
28 STORE_NAME
31 LOAD_NAME
34 LOAD_ATTR
37 CALL_FUNCTION
40 PRINT_ITEM
41 PRINT_NEWLINE
42 LOAD_NAME
45 LOAD_ATTR
48 CALL_FUNCTION
51 PRINT_ITEM
52 PRINT_NEWLINE
53 LOAD_CONST
56 RETURN_VALUE
dis输出说明: 第一列是代码的行数, 第二列是指令的偏移量, 第三列是可视化指令, 第四列是参数, 第五列是指令根据参数计算或者查找的结果咱们可以看到 第4列 和第五列, 分别就是对应: print A.f() 和 print a.f()
他们都是同样的字节码, 都是从所在的codeobject中的co_name取出参数对应的名字, 正因为参数的不同, 所以它们分别取到 A 和 a,下面我们需要来看看 LOAD_ATTR 的作用是什么:
//取自: python2.7/objects/ceval.c
TARGET(LOAD_ATTR)
w = GETITEM(names, oparg);
// 从co_name 取出 f
v = TOP();
// 将刚才压入栈的 A/a 取出来
x = PyObject_GetAttr(v, w); // 取得真正的执行函数
Py_DECREF(v);
SET_TOP(x);
if (x != NULL) DISPATCH();
通过 SET_TOP, 已经将我们需要真正执行的函数压入运行时栈, 接下来就是通过 CALL_FUNCTION 来调用这个函数对象, 继续来看看具体过程:
//取自: python2.7/objects/ceval.c
TARGET(CALL_FUNCTION)
PyObject **
PCALL(PCALL_ALL);
sp = stack_
#ifdef WITH_TSC
x = call_function(&sp, oparg, &intr0, &intr1);
x = call_function(&sp, oparg);
// 细节请往下看
stack_pointer =
if (x != NULL) DISPATCH();
static PyObject *
call_function(PyObject ***pp_stack, int oparg)
int na = oparg & 0
// 位置参数个数
int nk = (oparg&&8) & 0
// 关键位置参数的个数
int n = na + 2 *
// 总的个数和
PyObject **pfunc = (*pp_stack) - n - 1;
// 当前栈位置-参数个数,得到函数对象
PyObject *func = *
PyObject *x, *w;
... // 省略前面细节, 只看关键调用
if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
/* optimize access to bound methods */
PyObject *self = PyMethod_GET_SELF(func);
PCALL(PCALL_METHOD);
PCALL(PCALL_BOUND_METHOD);
Py_INCREF(self);
func = PyMethod_GET_FUNCTION(func);
Py_INCREF(func);
Py_SETREF(*pfunc, self);
Py_INCREF(func);
READ_TIMESTAMP(*pintr0);
if (PyFunction_Check(func))
x = fast_function(func, pp_stack, n, na, nk);
x = do_call(func, pp_stack, na, nk);
READ_TIMESTAMP(*pintr1);
Py_DECREF(func);
咱们来捋下调用顺序:
CALL_FUNCTION -& call_function -& 根据函数的类型 -& 执行对应的操作
当程序运行到call_function时, 主要有的函数类型判断有:
PyCFunction,
PyMethod, PyFunction在这里, 虚拟机已经判断出func是不属于PyCFunction, 所以将会落入上面源码的判断分支中, 而它将要做的,就是分别通过 PyMethod_GET_SELF, PyMethod_GET_FUNCTION 获得self对象和func函数, 然后通过调用 Py_SETREF(*pfunc, self):
// Py_SETREF 定义如下
#define Py_SETREF(op, op2)
PyObject *_py_tmp = (PyObject *)(op);
(op) = (op2);
Py_DECREF(_py_tmp);
} while (0)
可以看出, Py_SETREF是用这个self对象替换了pfunc指向的对象了, 而pfunc在上面已经提及到了, 就是当时压入运行时栈的函数对象. 除了这几步, 还有更重要的就是, na 和 n 都分别自增1看回上面的 a.f(), 咱们可以知道, 它是不需要参数的, 所以理论上 na,nk和n都是0, 但是因为f是method(方法), 经过上面一系列操作, 它将会传入一个self,而na也会变成1, 又因为*pfunc已经被替换成self, 相应代码:
if (PyFunction_Check(func))
x = fast_function(func, pp_stack, n, na, nk);
x = do_call(func, pp_stack, na, nk);
所以它不再进入function的寻常路了, 而是走do_call, 然后就开始真正的调用; 其实这个涉及到Python调用函数的整个过程, 因为比较复杂, 后期找个时间专门谈谈这个
聊到这里, 我们已经大致清楚, 一个method(方法) 在调用时所发生的过程.明白了函数和方法的本质区别, 那么回到主题上 来说下 Unbound 和 Bound, 其实这两者差别也不大. 从上面我们得知, 一个方法的创建, 是需要self, 而调用时, 也会使用self,而只有实例化对象, 才有这个self, class是没有的, 所以像下面的执行, 是失败的额
class A(object):
def f(self):
print '#### 各自方法等效调用 ####'
print '## 类方法 %s' % A.f()
print '## 实例方法 %s' % a.f()
## 输出结果 ##
#### 各自方法等效调用 ####
Traceback (most recent call last):
File "C:/Users/Administrator/ZGZN_Admin/ZGZN_Admin/1.py", line 20, in &module&
print '## 类方法 %s' % A.f()
TypeError: unbound method f() must be called with A instance as first argument (got nothing instead)
错误已经很明显了: 函数未绑定, 必须要将A的实例作为第一个参数既然它要求第一个参数是 A的实例对象, 那我们就试下修改代码:
class A(object):
def f(self):
print '#### 各自方法等效调用 ####'
print '## 类方法 %s' % A.f(a)
#传入A的实例a
print '## 实例方法 %s' % a.f()
## 结果 ##
#### 各自方法等效调用 ####
## 类方法 1
## 实例方法 1
可以看出来, Bound 和 Unbound判断的依据就是, 当方法真正执行时, 有没有传入实例, A.f(a) 和 a.f() 用法的区别只是在于, 第一种需要人为传入实例才能调用, 而第二种, 是虚拟机帮我们做好了传入实例的动作, 不用我们那么麻烦而已, 两种方法本质上是等价的欢迎各位大神指点交流,转载请注明来源:
0 收藏&&|&&3
你可能感兴趣的文章
1 收藏,1.5k
1 收藏,61
随着我们越来越频繁使用Python, 我们难免会接触到类, 接触到类属性和方法.但是很多新手包括我, 不知道方法 和 函数 的区别,这次简单来讨论下, 如果有哪里认识不正确, 希望大神提点指教!
随着我们越来越频繁使用Python, 我们难免会接触到类, 接触到类属性和方法.但是很多新手包括我, 不知道方法 和 函数 的区别,这次简单来讨论下, 如果有哪里认识不正确, 希望大神提点指教!
分享到微博?
我要该,理由是:
在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?scala中方法和函数的区别_百度知道
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
scala中方法和函数的区别
我有更好的答案
/zhidao/pic/item/342ac65c409c9813b07ecb8088dd.jpg" target="_blank" title="点击查看大图" class="ikqb_img_alink">4.在需要函数的地方,如果传递一个方法,会自动进行ETA展开(把方法转换为函数)如果我们直接把一个方法赋值给变量会报错。如果我们指定变量的类型就是函数,那么就可以通过编译,如下:当然我们也可以强制把一个方法转换给函数,这就用到了scala中的部分应用函数:5.传名参数本质上是个方法传名参数实质上是一个参数列表为空的方法,如下:如上代码实际上定义了一个方法m1,m1的参数是个传名参数(方法)。由于对于参数为空的方法来说,方法名就是方法调用,所以List(x,x)实际上是进行了两次方法调用。由于List(x,x)是进行了两次方法调用,所以得到两个不同的值。如果我们稍微修改一下函数的m1的定义,把x先缓存起来,结果就会跟以前大不一样。。如下:其实上述函数的定义方式跟如下定义方式等同:在如上的例子中,所以这种使用方式是完全正确的。但是我们把方法名当成最终表达式来使用的话,我们首先定义了一个方法m,接着有定义了一个函数f。接着我们把函数名(函数值)当作最终表达式来用。而函数不能省略参数列表3。上述new Function2[Int.jpg" target="_blank" title="点击查看大图" class="ikqb_img_alink">在如上的例子中./zhidao/wh%3D450%2C600/sign=d77d5a5ef61fa102fb9fc/96dda144addadcbef8435,有时方法上还有注解Scala中既有函数也有方法,大多数情况下我们都可以不去理会他们之间的区别,Int](){}其实是定义并实例化一个实现了Function2特质的类的对象。apply是scala中的语法糖:对一个对象obj上调用obj()。但是有时候我们必须要了解他们之间的不同./zhidao/wh%3D450%2C600/sign=eb573c969616fdfad839ceea81bfa062/6a63fcbfcfd8f9a182./zhidao/wh%3D450%2C600/sign=ed0b97b507dc/0b7b0c2c11dfa8eccedd.baidu.baidu。如://g。Scala中的方法跟Java的方法一样。Scala中用22个特质(trait)抽象出了函数的概念。这22特质从Function1到Function22如上图中的Function10代表的是:有10个形参://h.函数必须要有参数列表,而方法可以没有参数列表由于Function2是特质:<a href="http://e.hiphotos,Int。具体的差异://b。Scala中的函数是一个完整的对象
采纳率:96%
来自团队:
为您推荐:
其他类似问题
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;2被浏览230分享邀请回答11 条评论分享收藏感谢收起Predef.print(1) // 调用method
print(1) // 还是调用method
print.apply(1) // 编译错误,因为print不是个函数
val f: Int =& Int = { x: Int =& x + 1 } // 狭义的function,Int =& Int相当于Function1[Int, Int]
f(1) // 调用function
f.apply(1) // 调用f上的apply method,等价于f(1)
val p: Any =& Unit = print // eta-conversion,现在p是个狭义的function
p(1) // 调用function
p.apply(1) // 调用p上的apply method,等价于p(1)
15 条评论分享收藏感谢收起写回答

我要回帖

更多关于 方法和函数的区别 的文章

 

随机推荐