定义函数时不带括号?

发布于 2024-12-08 17:21:30 字数 378 浏览 0 评论 0原文

我知道我的问题可能听起来很愚蠢,而且语言定义中可能有一些东西明确禁止这个概念,但由于我不知道这个禁止,我想知道是否有人可以解释它。简而言之,我想定义一个可以从 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

缺⑴份安定 2024-12-15 17:21:30

你会在某个地方得到一些语法。您可以尝试类似的操作:

import os
class Shell(object):
    @property
    def pwd(self):
        print os.getcwd()

然后在解释器中运行:

>>> s = Shell()
>>> s.pwd
/tmp

You're going to get some syntax in there somewhere. You could try something like:

import os
class Shell(object):
    @property
    def pwd(self):
        print os.getcwd()

And then in your interpreter, run:

>>> s = Shell()
>>> s.pwd
/tmp
迷荒 2024-12-15 17:21:30

如果不修改语言或 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 即可执行。

我忘记了您还可以执行以下操作:

class Pwd(object):
    def __repr__(self):
        # do pwd command
        # return result in string form
pwd = Pwd()

现在,当您在 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 well x = !pwd. It even lets you call single argument functions by writing f x instead of f(x).

BTW Haskell is a language that uses spaces for list of arguments, i.e: f(1,2,3) in Python would be f 1 2 3 in Haskell, and in the shell any IO action can be executed by just typing action.

I forgot there's also a hack you can do:

class Pwd(object):
    def __repr__(self):
        # do pwd command
        # return result in string form
pwd = Pwd()

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.

╰沐子 2024-12-15 17:21:30

这是不可能的。对变量的裸引用(例如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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文