如果函数或方法调用中省略括号,则意味着什么?
- 2024-12-16 08:35:00
- admin 原创
- 153
问题描述:
我有这个示例代码:
class objectTest():
def __init__(self, a):
self.value = a
def get_value(self):
return self.value
a = objectTest(1)
b = objectTest(1)
print(a == b)
print(a.get_value() == b.get_value)
print(a.get_value() == b.get_value())
print(a.get_value == b.get_value)
显示结果为:
False
False
True
False
为什么这不会导致错误?get_value
是一个方法,那么为什么我们可以这样使用它而不先调用它呢?
另请参阅:在 Python 中,“<function at ...>”是什么意思?
解决方案 1:
如上所述,函数和方法是一等对象。通过在末尾添加一些括号(方括号)来调用它们。但看起来你想要更多的动机来了解为什么 Python 甚至允许我们这样做。我们为什么要关心函数是否是一等的?
有时您不想调用它们,而是想要传递对可调用函数本身的引用。
from multiprocessing import Process
t = Process(target=my_long_running_function)
如果你在上面后面加上括号,它会my_long_running_function
在主线程中运行;这几乎不是你想要的!你想给Process
你的可调用函数一个引用,它将在新的进程中运行。
有时您只想指定可调用函数并让其他东西...
def do_something(s):
return s[::-1].upper()
map(do_something,['hey','what up','yo'])
Out[3]: ['YEH', 'PU TAHW', 'OY']
(map
在本例中)填写其参数。
也许您只是想将一堆可调用函数放入某个集合中,然后以动态方式获取所需的函数。
from operator import *
str_ops = {'<':lt,'>':gt,'==':eq} # etc
op = str_ops.get(my_operator)
if op:
result = op(lhs,rhs)
以上是将运算符的字符串表示映射到其实际操作的一种方法。
解决方案 2:
Python 中的函数和方法本身也是对象。因此,你可以像比较任何其他对象一样比较它们。
>>> type(a.get_value)
<type 'instancemethod'>
>>> type(a.get_value())
<type 'int'>
当然,通常情况下,您不会将方法相互比较或与其他任何东西进行比较,因为它不是很有用。它很有用的一个地方是当您想要将一个函数传递给另一个函数时。一种常见的用法是用于不区分大小写的字符串排序,方法是告诉它使用str.lower
作为生成排序键的方法:
>>> list_of_strings=['A','b','C']
>>> sorted(list_of_strings)
['A', 'C', 'b']
>>> sorted(list_of_strings, key=str.lower)
['A', 'b', 'C']
解决方案 3:
def mul(a, b):
return a * b
def add(a, b):
return a + b
def do(op, a, b):
return op(a, b)
do(add, 2, 3) # return 5
解决方案 4:
print(a.get_value() == b.get_value) # 1
print(a.get_value() == b.get_value()) # 2
print(a.get_value == b.get_value) # 3
1)调用的返回值是否a.get_value()
等于方法的返回值b.get_value
?
2)a.get_value()
返回的结果是否相同b.get_value()
?
3)方法引用是否a.get_value
等于方法引用b.get_value
?
这是完全有效的 Python :)
解决方案 5:
一些评论者想要一个示例来说明这在何处有用。一个应用是在线程中。我们需要将目标传递给线程而不使用括号。否则,目标将在主线程中创建,这正是我们要避免的。
例子:
在 test1.py 中我调用 ThreadTest 而不使用括号。test_thread 在线程中启动并允许 test1.py 继续运行。
在 test2.py 中,我传递了 ThreadTest() 作为目标。在这种情况下,线程不允许 test2.py 继续运行。
测试1.py
import threading
from thread_test import ThreadTest
thread = threading.Thread(target=ThreadTest)
thread.start()
print('not blocked')
测试2.py
import threading
from thread_test import ThreadTest
thread = threading.Thread(target=ThreadTest())
thread.start()
print('not blocked')
测试线程.py
from time import sleep
class ThreadTest():
def __init__(self):
print('thread_test started')
while True:
sleep(1)
print('test_thread')
test1.py 的输出:
thread_test started
not blocked
test_thread
test_thread
test_thread
test2.py 的输出:
thread_test started
test_thread
test_thread
test_thread
我在 Linux Mint 上使用 python3.5。
解决方案 6:
不带括号的函数和带括号的函数之间的区别在于,当使用括号时,您将获得该函数的输出,而当您使用不带括号的函数时,您将创建该函数的副本。例如
def outerFunction(text):
text = text
def innerFunction():
print(text)
return innerFunction()
if __name__ == '__main__':
outerFunction('Hey!')
x = outerFunction
y = x
x('Hey i am busy can you call me later')
y('this is not a function')
这里我们将函数 outerFunction 复制到 x 然后将 y 复制到 x。
- 2025年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)