Определение функции без скобок?
Я понимаю, что мой вопрос может казаться глупым и что в определении языка может быть что-то явно запрещающее это понятие, но поскольку я не знаю об этом запрете, мне было интересно, может ли кто-нибудь пролить свет на него, Короче говоря, я хотел бы определить функцию 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
, но это еще менее очевидно и уродливее).