Python中有函数吗,还是所有东西都是方法?
或者说,所有东西都是一个方法吗?
因为所有东西都是对象,所以一个
def whatever:
其实就是那个文件 file.py 的一个方法,对吧?
3 个回答
嗯……你可以把“whatever”当作一个普通的函数来使用,就像在文件的命名空间里一样。
在Python中,文件名为file.py
的文件并不一定包含一个叫file
的类,这和Java中的file.java
文件是不同的。在Java中,文件名和类名是对应的,但在Python里,文件其实是一个模块,简单来说就是一个命名空间(更像Java中的包,而不是类)。
来看下面这个file.py
的例子:
def whatever_func():
print "What ever function"
class SomeClass(object):
def whatever_meth(self):
print "What ever method"
在上面的例子中,file
这个模块/命名空间里面有一个普通的函数叫whatever_func
,还有一个类SomeClass
,这个类里面有一个方法叫whatever_meth
。
Python 有函数。因为一切都是对象,所以 函数也是对象。
以你的例子为例:
>>> def whatever():
... pass
...
>>> whatever
<function whatever at 0x00AF5F30>
当我们使用 def
时,我们创建了一个对象,这个对象就是一个函数。比如,我们可以查看这个对象的一个属性:
>>> whatever.func_name
'whatever'
回答你的问题——whatever()
不是 file.py 的一个 方法。更好的理解方式是把它看作是一个函数对象,它的名字是 whatever
,在 file.py
的全局命名空间中。
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__d
oc__': None, 'whatever': <function whatever at 0x00AF5EB0>}
换个角度来看,我们完全可以把名字 whatever
绑定到一个完全不同的对象上:
>>> whatever
<function whatever at 0x00AF5F30>
>>> whatever = "string"
>>> whatever
'string'
还有其他方法可以创建函数对象。例如,lambda 表达式:
>>> somelambda = lambda x: x * 2
>>> somelambda
<function <lambda> at 0x00AF5F30>
方法就像是一个对象的属性,它是一个函数。之所以称之为方法,是因为方法会绑定到对象上。这使得对象作为第一个参数传递给函数,我们通常称这个参数为 self
。
让我们定义一个类 SomeClass
,里面有一个方法 somemethod
和一个实例 someobject
:
>>> class SomeClass:
... def somemethod(one="Not Passed", two="Not passed"):
... print "one = %s\ntwo = %s" % (one,two)
...
>>> someobject = SomeClass()
我们来看一下 somemethod
作为一个属性:
>>> SomeClass.somemethod
<unbound method SomeClass.somemethod>
>>> someobject.somemethod
<bound method SomeClass.somemethod of <__main__.SomeClass instance at 0x00AFE030
我们可以看到它是对象上的一个绑定方法,而在类上是一个未绑定的方法。现在让我们调用这个方法,看看会发生什么:
>>> someobject.somemethod("Hello world")
one = <__main__.SomeClass instance at 0x00AFE030>
two = Hello world
由于这是一个绑定方法,somemethod
接收到的第一个参数是对象,第二个参数是方法调用中的第一个参数。让我们在类上调用这个方法:
>>> SomeClass.somemethod("Hello world")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method somemethod() must be called with SomeClass instance as first argument (got str instance instead)
Python 会报错,因为我们试图在没有提供合适类型对象的情况下调用这个方法。所以我们可以通过“手动”传递对象来解决这个问题:
>>> SomeClass.somemethod(someobject,"Hello world")
one = <__main__.SomeClass instance at 0x00AFE030>
two = Hello world
你可能会在想要从父类调用特定方法时使用这种类型的方法调用——在类上调用一个方法。
(可以 将一个函数绑定到类上,使其成为一个方法,但这通常不是你需要做的事情。)