定义函数时不带括号?
我知道我的问题可能听起来很愚蠢,而且语言定义中可能有一些东西明确禁止这个概念,但由于我不知道这个禁止,我想知道是否有人可以解释它。简而言之,我想定义一个可以从 python shell 调用的 python 函数,但我想避免使用括号。在某些情况下,函数不需要参数,那么括号似乎仅表明我们正在处理一个函数。例如,如果有人想要打印当前工作目录。我可以定义一个函数
def pwd():
print os.getcwd()
,然后我可以从 shell 调用它,
pwd()
但是如果我想要一个可以调用的函数,怎么办?
pwd
这可能吗?
I understand that my question might sound stupid, and that there might be something in the language definition that explicitly prohibits this notion, but since I don't know about this prohibition, I was wondering whether someone could shed some light on it. In short, I would like to define a python function that I could call from the python shell, but I would like to avoid the brackets. There are cases when a function does not require an argument, and then the bracket only seems to indicate that we are dealing with a function. Such an example would be, if one wants to print the current working directory. I can define a function as
def pwd():
print os.getcwd()
and then I can call it from the shell as
pwd()
But what if I would like to have a function that I can call as
pwd
Is this possible at all?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你会在某个地方得到一些语法。您可以尝试类似的操作:
然后在解释器中运行:
You're going to get some syntax in there somewhere. You could try something like:
And then in your interpreter, run:
如果不修改语言或 shell,就无法做到这一点。
如果你想使用Python作为shell,你真的应该尝试IPython,它允许你定义可以使用的宏无需输入尽可能多的键。它还允许您执行
!pwd
,您也可以将其分配给变量x = !pwd
。它甚至允许您通过编写f x
而不是f(x)
来调用单参数函数。BTW Haskell 是一种使用空格作为参数列表的语言,即:Python 中的
f(1,2,3)
在 Haskell 中将是f 1 2 3
,而在shell 中的任何 IO 操作只需输入action
即可执行。我忘记了您还可以执行以下操作:
现在,当您在 shell 中键入 pwd 时,它将调用 __repr__ 来获取对象的字符串表示形式。不幸的是,您只能返回一个字符串(而不是说,如果您正在实现 ls,则表示当前目录中的文件/文件夹的字符串列表),因为 python 语言强制这样做。
You can't do this without modifying the language or the shell.
If you want to use Python as a shell, you should really try IPython, it allows you to define macros that you can use without typing as many keys. It also lets you do
!pwd
, you can assign this to a variable as wellx = !pwd
. It even lets you call single argument functions by writingf x
instead off(x)
.BTW Haskell is a language that uses spaces for list of arguments, i.e:
f(1,2,3)
in Python would bef 1 2 3
in Haskell, and in the shell any IO action can be executed by just typingaction
.I forgot there's also a hack you can do:
Now when you type pwd in the shell, it will call
__repr__
to get a string representation of the object. Unfortunately, you're restricted to returning a string (as opposed to say, a list of strings representing the files/folders in the current directory, if you were implementing ls) because the python language forces this.这是不可能的。对变量的裸引用(例如
pwd
)不会执行任何特殊操作,它只是检索存储在该变量中的引用。如果该变量绑定到函数,则此引用是对函数的引用,但无论哪种方式,它都只是一个引用,仅此而已。要实际调用任何内容,您必须使用函数调用语法 -表达式 '(' arglist ')'
。现在,这不适用于对象(即任何对象)的属性,因为获取成员在技术上已经是函数调用,并且可以被覆盖。实际上,可以通过多种方式影响
obj.member
的计算结果,最重要的是__getattr__
、__getattribute__
和__get__
在描述符中。对于后两者,有与设置属性等效的操作(是的,这是一个不同的操作)。所有这些都记录在语言参考中。使用它来隐式调用过程(而不是 getter)仍然是一个非常糟糕的主意,因为它是违反直觉的,使代码不那么明显,并且除了节省两个括号之外绝对没有任何好处。它还不允许获取对函数的引用,这使得使用它进行函数式和函数式编程非常不方便(您可以使用
lambda:obj.pwd
,但这甚至不太明显且更丑)。It is not possible. A bare reference to a variable (e.g.
pwd
) never does anything special, it just retrieves the reference stored in that variable. If that variable was bound to a function, this reference is a reference to a function, but either way it's just a reference and nothing more. To actually call anything, you have to use the syntax for function calls -expression '(' arglist ')'
.Now, this doesn't apply to properties of objects (i.e. of anything), as getting a member is technically already a function call, and can be overridden. There are actually numerous ways one can influence what
obj.member
evaluates to, the most important ones being__getattr__
,__getattribute__
, and__get__
in a descriptor. For the latter two, there are equivalents to setting attributes (yes, that's a distinct operation). All of these are documented in the language reference.It'd still a pretty bad idea to use this to implicitly call a procedure (as opposed to getters), as it's counter-intuitive, makes the code less obvious and has absolutely no benefit aside from saving you two parens. It would also disallow getting a reference to the function, which makes functional and functional-inspired programming with it very inconvenient (you could use
lambda: obj.pwd
, but that's even less obvious and uglier).