Определение функции без скобок?

Я понимаю, что мой вопрос может казаться глупым и что в определении языка может быть что-то явно запрещающее это понятие, но поскольку я не знаю об этом запрете, мне было интересно, может ли кто-нибудь пролить свет на него, Короче говоря, я хотел бы определить функцию python, которую я мог бы вызвать из оболочки python, но я бы хотел избежать скобок. Бывают случаи, когда функция не требует аргумента, и тогда скобка только указывает, что мы имеем дело с функцией. Например, если вы хотите распечатать текущий рабочий каталог. Я могу определить функцию как

def pwd():
    print os.getcwd()

а затем я могу вызвать его из оболочки как

pwd()

Но что, если я хотел бы иметь функцию, которую я могу назвать как

pwd

Возможно ли это вообще?

Ответ 1

Вы не можете сделать это без изменения языка или оболочки.

Если вы хотите использовать Python в качестве оболочки, вам действительно нужно попробовать IPython, он позволяет вам определять макросы, которые вы можете использовать не набрав столько ключей. Он также позволяет вам выполнять !pwd, вы также можете назначить эту переменную x = !pwd. Он даже позволяет вам вызывать одиночные функции аргументов, записывая f x вместо f(x).

BTW Haskell - это язык, который использует пробелы для списка аргументов, т.е. f(1,2,3) в Python будет f 1 2 3 в Haskell, а в оболочке любое действие IO может быть выполнено просто набрав action.

Я тоже забыл, что вы можете сделать взлом:

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

Теперь, когда вы вводите pwd в оболочке, он вызовет __repr__, чтобы получить строковое представление объекта. К сожалению, вы ограничены возвратом строки (в отличие от, скажем, списка строк, представляющих файлы/папки в текущем каталоге, если вы выполняли ls), потому что язык python заставляет это.

Ответ 2

Вы где-нибудь получите синтаксис. Вы можете попробовать что-то вроде:

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

И затем в вашем интерпретаторе запустите:

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

Ответ 3

Это невозможно. Голая ссылка на переменную (например, pwd) никогда не делает ничего особенного, она просто извлекает ссылку, хранящуюся в этой переменной. Если эта переменная была привязана к функции, эта ссылка является ссылкой на функцию, но в любом случае это просто ссылка и не более того. Чтобы на самом деле вызывать что-либо, вы должны использовать синтаксис для вызовов функций - expression '(' arglist ')'.

Теперь это не относится к свойствам объектов (т.е. чего-либо), поскольку получение элемента технически уже является вызовом функции и может быть переопределено. На самом деле существует множество способов влиять на оценку obj.member, причем наиболее важными являются __getattr__, __getattribute__ и __get__ в дескрипторе. Для последних двух есть эквиваленты для установки атрибутов (да, это отдельная операция). Все они задокументированы в справочной системе .

Было бы неплохой идеей использовать это для неявного вызова процедуры (в отличие от геттеров), поскольку она противоречит интуиции, делает код менее очевидным и не имеет абсолютно никакой выгоды, кроме сохранения двух парен. Также было бы запрещено получать ссылку на функцию, которая делает функциональное и функционально-вдохновляющее программирование очень неудобным (вы можете использовать lambda: obj.pwd, но это еще менее очевидно и уродливее).