Air
Air

Reputation: 8615

Accessing the print function from globals()

Apologies in advance for conflating functions and methods, I don't have time at the moment to sort out the terminology but I'm aware of the distinction (generally).

I'm trying to control what functions are run by my script via command-line arguments. After a lot of reading here and elsewhere, I'm moving in the direction of the following example.

# After connecting to a database with MySQLdb and defining a cursor...

cursor.execute(some_query_stored_earlier)
for row in cursor:
    for method_name in processing_methods:    # ('method1','method2', ...)
        globals()[method_name](row)

(Clarification: processing_methods is a tuple of user-defined strings via command-line argument(s) with nargs='*'.)

However, I'm running into problems with print (no surprise there). I would like print to be:

Let me acknowledge that I can make things easier on myself by eliminating the first and third criteria and simply doing:

for row in cursor:
    print row
    for method_name in processing_methods:
        globals[method_name](row)

But I really don't want to ALWAYS print every row in what will sometimes be a several-million-rows result. I did a future import, hoping that would solve my problem - no such luck. So I did a little exploring:

>>> from __future__ import print_function
>>> print
<built-in function print>

>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'print_function': _Feature((2, 6, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 65536), '__package__': None}

>>> a = "Hello, world!"
>>> print(a)
Hello, world!
>>> globals()['print'](a)

Traceback (most recent call last):
  File "<pyshell#33>", line 1, in <module>
    globals()['print'](a)
KeyError: 'print'              # Okay, no problem, obviously it's...

>>> globals()['print_function'](a)

Traceback (most recent call last):
  File "<pyshell#34>", line 1, in <module>
    globals()['print_function'](a)
AttributeError: _Feature instance has no __call__ method    # ...huh.

So then I did a little more reading, and this Q&A prompted some more exploring:

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>> __builtins__
<module '__builtin__' (built-in)>
>>> 'print' in dir(__builtins__)
True                                  # now we're getting somewhere!
>>> __builtins__.print something
SyntaxError: invalid syntax           # fair enough.
>>> __builtins__.print('something')
SyntaxError: invalid syntax           # wait, what?
>>> dir(__builtins__.print)
SyntaxError: invalid syntax           # -_-

Something is going on here that I just don't understand, and this other Q&A hasn't made it any clearer. I think the easy solution to my particular issue is going to be a mildly awkward wrapper like:

def printrows(row):
    print row             # assuming no future import, of course

But it's driving me crazy: Why can't I access print via the globals dictionary? Am I doing it wrong, or is it just something you can't do with built-in functions?

Upvotes: 2

Views: 1003

Answers (2)

brechin
brechin

Reputation: 589

If you do an otherwise seemingly useless assignment, it works the way I think you expected. I'm not an expert in the internals at work here, so I can't explain WHY this works, but it does.

>>> from __future__ import print_function
>>> row="Hello world"
>>> print = print
>>> globals()['print'](row)
Hello world

Upvotes: 2

user395760
user395760

Reputation:

Did you forget to repeat from __future__ import print_function when you opened a new shell for your second try (where you got all those syntax errors)? It works for me: https://ideone.com/JOBAAk

Upvotes: 2

Related Questions