111

The print used to be a statement in Python 2, but now it became a function that requires parenthesis in Python 3.

Is there anyway to suppress these parenthesis in Python 3? Maybe by re-defining the print function?

So, instead of

print ("Hello stack over flowers")

I could type:

print "Hello stack over flowers"
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Laura
  • 1,383
  • 3
  • 9
  • 6
  • 6
    Is there a particular reason you want to do this? Or are you just curious? It is generally not good practice to redefine keywords even if it *is* possible. – Michael S Priz Aug 20 '15 at 15:57
  • 11
    Out of curiosity, why are people down voting this? I do not understand how it lies outside of SO guidelines. – Michael S Priz Aug 20 '15 at 15:58
  • You may be interested in [this SO Q/A](http://stackoverflow.com/questions/214881/can-you-add-new-statements-to-pythons-syntax) – Michael S Priz Aug 20 '15 at 16:04
  • 40
    I am using Python 3. However, typing `()` all the time is unnecessarily time consuming. – Laura Aug 20 '15 at 16:20
  • 2
    If this is your goal then I suggest looking for ways to cut-down on the number of print statements you have to write instead of trying to workaround coding standards. Is there a particular program you are writing that requires a lot of print statements? If so perhaps you should open a new question about that specific program. – Michael S Priz Aug 20 '15 at 16:37
  • 12
    Michael, you don't seem so kind. Did I do something wrong? I am asking an honest question even if sounds like a workaround coding standards for you. If it was so "standard" they wouldn't change it in Python 3, would they? – Laura Aug 20 '15 at 18:01
  • 8
    I suppose I should have said "language specifications" :) I apologize if anything I said came across as offensive. I am only trying to help you get the most out of SO. – Michael S Priz Aug 20 '15 at 18:07
  • 3
    A good reason for this question is the gargantuan amount of 2.x code snippets on the web that use embedded print "foo" statements instead of print("foo") statements. If you copy/paste 2.x code snippets, it requires editing, commenting or refactoring, which is more time-consuming than typing a single extra character. – TheProletariat Dec 16 '16 at 19:08
  • 4
    I don't understand why would anyone up-vote an answer to a different question. Unfortunately in the real world we are not always able to rewrite our entire project, and please don't offer me Python3 migration tools here - some project have to also be backward compatible. "Impossible" would also be a great answer - from a knowledgeable individual. – Ofer Rahat Oct 18 '17 at 07:25

10 Answers10

34

Although you need a pair of parentheses to print in Python 3, you no longer need a space after print, because it's a function. So that's only a single extra character.

If you still find typing a single pair of parentheses to be "unnecessarily time-consuming," you can do p = print and save a few characters that way. Because you can bind new references to functions but not to keywords, you can only do this print shortcut in Python 3.

Python 2:

>>> p = print
  File "<stdin>", line 1
    p = print
            ^
SyntaxError: invalid syntax

Python 3:

>>> p = print
>>> p('hello')
hello

It'll make your code less readable, but you'll save those few characters every time you print something.

TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
16

Using print without parentheses in Python 3 code is not a good idea. Nor is creating aliases, etc. If that's a deal breaker, use Python 2.

However, print without parentheses might be useful in the interactive shell. It's not really a matter of reducing the number of characters, but rather avoiding the need to press Shift twice every time you want to print something while you're debugging. IPython lets you call functions without using parentheses if you start the line with a slash:

Python 3.6.6 (default, Jun 28 2018, 05:43:53)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: var = 'Hello world'

In [2]: /print var
Hello world

And if you turn on autocall, you won't even need to type the slash:

In [3]: %autocall
Automatic calling is: Smart

In [4]: print var
------> print(var)
Hello world
kxmh42
  • 3,121
  • 1
  • 25
  • 15
11

Use Autohotkey to make a macro. AHK is free and dead simple to install. www.autohotkey.com

You could assign the macro to, say, alt-p:

!p::send print(){Left}

That will make alt-p put out print() and move your cursor to inside the parens.

Or, even better, to directly solve your problem, you define an autoreplace and limit its scope to when the open file has the .py extension:

#IfWinActive .py            ;;; scope limiter
:b*:print ::print(){Left}   ;;; I forget what b* does. The rest should be clear 
#IfWinActive                ;;; remove the scope limitation

This is a guaranteed, painless, transparent solution.

Harry Binswanger
  • 1,069
  • 10
  • 12
  • `b` means "use backspace to delete `print`", `*` means no further ending character like `Space` needed to activate replace" (https://www.autohotkey.com/docs/Hotstrings.htm) – Sebastian Nov 05 '22 at 09:15
5

No. That will always be a syntax error in Python 3. Consider using 2to3 to translate your code to Python 3

holdenweb
  • 33,305
  • 7
  • 57
  • 77
  • 16
    I am using Python 3. I just want to avoid typing parenthesis all the time. `shift` + `9` ..... then again `shift` + `0` is exhaustive. – Laura Aug 20 '15 at 16:26
  • Sorry that the function calls make the typing difficult for you. I'm a pretty crappy typist myself, so even though I don't have any physical disability I do what I can to minimize use of shifted keys. – holdenweb Aug 20 '15 at 20:35
  • Apparently, no one appreciate the simplicity of the UP arrow when using bash 'history recall'. It's simple. The same way with `print`, it should be unencumbered by useless debugging techniques such as a pair of parentheses. – John Greene Dec 12 '18 at 03:45
  • There are arguments for that, which were extensively rehearsed before the introduction of Python 3. While the extra parentheses may be inconvenient for us poor typists, the flexibility offered by the ability to redefine `print` was felt to be worth it, I believe. – holdenweb Dec 12 '18 at 09:03
4

The AHK script is a great idea. Just for those interested I needed to change it a little bit to work for me:

SetTitleMatchMode,2         ;;; allows for a partial search 
#IfWinActive, .py           ;;; scope limiter to only python files
:b*:print ::print(){Left}   ;;; I forget what b* does
#IfWinActive                ;;; remove the scope limitation
TokyoMike
  • 83
  • 7
  • `b` means "use backspace to delete `print`", `*` means no further ending character like `Space` needed to activate replace" (https://www.autohotkey.com/docs/Hotstrings.htm) – Sebastian Nov 05 '22 at 09:16
4

You can use operator oveloading:

class Print:
    def __lt__(self, thing):
    print(thing)

p = Print()

p < 'hello'   #  ->  hello 

Or if you like use << like in c++ iostreams.

nadapez
  • 2,603
  • 2
  • 20
  • 26
3

I finally figured out the regex to change these all in old Python2 example scripts. Otherwise use 2to3.py.

Try it out on Regexr.com, doesn't work in NP++(?):

find:     (?<=print)( ')(.*)(')
replace: ('$2')

for variables:

(?<=print)( )(.*)(\n)
('$2')\n

for label and variable:

(?<=print)( ')(.*)(',)(.*)(\n)
('$2',$4)\n
alchemy
  • 954
  • 10
  • 17
  • 1
    Here is a regex that works in NP++ `(?<=print)( ')(.*)(')` `\('$2'\)` – Jack Jan 15 '19 at 18:35
  • Thanks @Jack, needed to escape the parentheses (just in replace?).. good to know. Also, I found a semi-related trick that Py3 recognizes having a space between `print ('string')`, so that the printable can more easily be highlighted and then use many editors' auto-close to add the parentheses and then quotes. – alchemy Jan 16 '19 at 19:19
1

You can't, because the only way you could do it without parentheses is having it be a keyword, like in Python 2. You can't manually define a keyword, so no.

1

In Python 3, print is a function, whereas it used to be a statement in previous versions. As @holdenweb suggested, use 2to3 to translate your code.

SPKB24
  • 37
  • 4
1

I have configured vim to auto-add the parens around my debug def calls when I write the file. I use a simple watcher that auto-runs my updates when the timestamp changes. And I defined CTRL+p to delete them all. The only caveat is that I have to have them alone on a line, which I pretty much always do. I thought about trying to save and restore my previous search-highlight. And I did find a solution on Stack. But it looked a little too deep for now. Now I can finally get back to debugging Ruby-style with a quick p<space><obj>.

function! PyAddParensToDebugs()
  execute "normal! mZ"
  execute "%s/^\\(\\s*\\)\\(p\\|pe\\|pm\\|pp\\|e\\|ppe\\)\\( \\(.*\\)\\)\\{-}$/\\1\\2(\\4)/"
  execute "normal! `Z"
endfunction

autocmd BufWrite *.py silent! call PyAddParensToDebugs()

map <c-p> :g/^\\s*\\(p\\\|pe\\\|pm\\\|pp\\\|e\\\|ppe\\)\\( \\\|\(\\)/d<cr>

I use these Python defs to do my debug printing.

def e():
    exit()
def pp(obj):
    pprint.PrettyPrinter(indent=4).pprint(obj)
def ppe(obj):
    pprint.PrettyPrinter(indent=4).pprint(obj)
    exit()
def p(obj):
    print(repr(obj))
def pe(obj):
    print(repr(obj))
    exit()
def pm():
    print("xxx")
Myles Prather
  • 171
  • 1
  • 12