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?
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
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.
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).