Определение функции без скобок? - PullRequest
11 голосов
/ 08 октября 2011

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

def pwd():
    print os.getcwd()

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

pwd()

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

pwd

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

Ответы [ 3 ]

10 голосов
/ 08 октября 2011

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

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

. Кстати, 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 вызывает это.

9 голосов
/ 08 октября 2011

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

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

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

>>> s = Shell()
>>> s.pwd
/tmp
4 голосов
/ 08 октября 2011

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

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

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

...