Reset print function in python - python

I just started looking into the Python and need help on this.
In the shell I did
>>> print = 1
Now when I tried to print anything like
>>> print ("hello")
I am getting "TypeError: 'int' object is not callable, obviously because print in now a int
I am able to figure out that if I restart the shell, print starts working fine again.
What I want to know that how can I reset the print to its original state i.e. print to console without restarting the shell?

You created a global that masks the built-in name. Use del to remove the new global; Python will then find the built-in again:
del print
Python looks for print through the current scope (in functions that includes locals and any parent scopes), then globals, then the built-in namespace, and it is in the latter that the print() function lives.

You have "masked" the builtin print function by creating a variable with the same name. You could do one of three things:
Quit python and restart it. This is guaranteed to work. :-)
Delete the variable you created, as suggested by #MartijnPieters.
Change the new variable to refer to the builtins.print function.
For the last option, you'll need to import builtins.
>>> print = 1
>>> print("Hello")
>>> Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
>>> import builtins
>>> dir(builtins)
>>> ['ArithmeticError', 'AssertionError', 'AttributeError',
...
'print',
...
'tuple', 'type', 'vars', 'zip']
>>> print=builtins.print
>>> print("Hello")
>>> Hello

Related

Decorators, calling functions without parenthesis?

I'm teaching myself how to code with the help of some online tutorials. I've encountered "decorators", I can seem to understand how it works but something bothers me. Here's the code given:
def decor(func):
def wrap():
print("-----------")
func()
print("-----------")
return wrap
def print_text():
print("Hello World")
decorated = decor(print_text)
decorated()
output:
-----------
Hello World
-----------
The things that I want to understand are:
Why do you have to call "return wrap" instead of "return wrap()"? Whereas if you don't you'll get a "TypeError: 'NoneType' object is not callable.
When I assigned the value of decorated variable. How come I also had to use "print_text" rather than "print_text()" whereas it'll raise the same TypeError if I do?
When I used the variable "decorated". Why did I have to call it like a function (adding () at the end). When I call it using "decorated" or "print(decorated)" it says something completely different?
Sorry for the dumb questions. But I'm just starting out so please bear with me. Also please make your responses beginner-friendly. Thank you
In Python, just about everything is an object. Functions are objects too. You can reference them by their name:
>>> def print_text():
... print("Hello World")
...
>>> print_text # **no** call here, this is just referencing the object
<function print_text at 0x10e3f1c80>
>>> print_text() # With a call, so now we *run* the function
Hello World
Adding () to the name told Python to call the function, which caused it to actually execute the function body, without the call, it is just showing you what the name references.
You can assign function objects to other names too. Those other names can still be called, invoking the function:
>>> other_name = print_text
>>> other_name
<function print_text at 0x10e3f1c80>
>>> other_name()
Hello World
So other_name is just another reference to the same object, and adding () (a call expression) causes the function object to be executed. print_text() and other_name() do the exact same thing, run the code inside the function.
That's what name func inside of decor() refers to; it is a reference to the same function object. You passed it in with decor(print_text). Only later on, inside wrapper() the expression func() calls that function object. If you passed in print_text() instead, you'd pass in the None object that function returned, and None can't be called:
>>> return_value = print_text()
Hello World
>>> return_value is None
True
>>> return_value()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
Next, return wrapper returns the newly created wrapper function object to the caller. If you did return wrapper(), you'd return the result of the function, not the function object itself.
The whole point of a decorator is to replace the original function object with a new object that does extra stuff, which is why a decorator returns that replacement object (in your example wrapper) so that in future when you call decorated(), you call that wrapper function doing something extra before and after calling the original function (via the func name, which references print_text()).
So what decor(some_function) does is return a new function object, one that'll print something, call the function object that was passed in, then print something else. That new function object can then be used to replace the old function object.

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:
among the methods that MIGHT be specified from the command line;
the default method when NO methods are specified from the command line;
not performed if ONLY OTHER methods are specified from the command line.
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?
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
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

Compiler Python, why are some wrong things overlooked?

I wrote a Python routine with a mistake in it: false instead of False. However, it was not discovered at compilation. The program had to run until this line to notify the wrongdoing.
Why is it so? What in the Python interpreter/compiler things make it work so?
Do you have some reference?
Due to Python's dynamic nature, it is impossible to detect undefined names at compile time. Only the syntax is checked; if the syntax is fine, the compiler generates the bytecode, and Python starts to execute the code.
In the given example, you will get a reference to a global name false. Only when the bytecode interpreter tries to actually access this global name, you will get an error.
To illustrate, here is an example. Do you think the following code executes fine?
globals()["snyfr".decode("rot13")] = 17
x = false
It actually does, since the first line dynamically generates a variable named false.
You can think of this as the interpreter being 'lazy' about when to look up names: it does so as late as possible, because other bits of the program can fiddle around with its dictionary of known variables.
Consider the program
>>> def foo():
... return false
...
>>> def bar():
... global false
... false = False
...
>>> foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in foo
NameError: global name 'false' is not defined
>>> bar()
>>> foo()
False
Notice that the first call to foo raised a NameError, because at the time that foo ran Python didn't know what false was. But bar then modified the global scope and inserted false as another name for False.
This sort of namespace-mucking allows for tremendous flexibility in how one writes programs. Of course, it also removes a lot of things that a more restrictive language could check for you.

How to set a variable by its name in Python?

EDIT 2 : since so many people are crying against the bad design this usecase can reveal. Readers of these question and answers should think twice before using it
I've trying to set a variable (not property) by it's name in Python :
foo = 'bar'
thefunctionimlookingfor('foo', 'baz')
print foot #should print baz
PS : the function to access a variable by its name (without eval) would be a plus !
EDIT : I do know dictionary exists, this kind of usage is discouraged, I've choose to use it for a very specific purpose (config file modification according to environment), that will let my code easier to read.
When you want variably-named variables, it's time to use a dictionary:
data = {}
foo = 'bar'
data[foo] = 'baz'
print data['bar']
Dynamically setting variables in the local scope is not possible in Python 2.x without using exec, and not possible at all in Python 3.x. You can change the global scope by modifying the dictionary returned by globals(), but you actually shouldn't. Simply use your own dictionary instead.
You can do something like:
def thefunctionimlookingfor(a, b):
globals()[a] = b
Usage:
>>> foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'q' is not defined
>>> thefunctionimlookingfor('foo', 'bar')
>>> foo
'bar'
But this is a terrible idea, as others have mentioned. Namespaces are a useful concept. Consider a redesign.
At the module level you can use setattr on the current module, which you can get from sys.modules:
setattr(sys.modules[__name__], 'name', 'value')
The locals() function returns a dictionary filled with the local variables.
locals()['foo'] = 'baz'
Are you looking for functions like these? They allow modifying the local namespace you happen to be in.
import sys
def get_var(name):
return sys._getframe(1).f_locals[name]
def set_var(name, value):
sys._getframe(1).f_locals[name] = value
def del_var(name):
del sys._getframe(1).f_locals[name]

How to generate a module object from a code object in Python

Given that I have the code object for a module, how do I get the corresponding module object?
It looks like moduleNames = {}; exec code in moduleNames does something very close to what I want. It returns the globals declared in the module into a dictionary. But if I want the actual module object, how do I get it?
EDIT:
It looks like you can roll your own module object. The module type isn't conveniently documented, but you can do something like this:
import sys
module = sys.__class__
del sys
foo = module('foo', 'Doc string')
foo.__file__ = 'foo.pyc'
exec code in foo.__dict__
As a comment already indicates, in today's Python the preferred way to instantiate types that don't have built-in names is to call the type obtained via the types module from the standard library:
>>> import types
>>> m = types.ModuleType('m', 'The m module')
note that this does not automatically insert the new module in sys.modules:
>>> import sys
>>> sys.modules['m']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'm'
That's a task you must perform by hand:
>>> sys.modules['m'] = m
>>> sys.modules['m']
<module 'm' (built-in)>
This can be important, since a module's code object normally executes after the module's added to sys.modules -- for example, it's perfectly correct for such code to refer to sys.modules[__name__], and that would fail (KeyError) if you forgot this step. After this step, and setting m.__file__ as you already have in your edit,
>>> code = compile("a=23", "m.py", "exec")
>>> exec code in m.__dict__
>>> m.a
23
(or the Python 3 equivalent where exec is a function, if Python 3 is what you're using, of course;-) is correct (of course, you'll normally have obtained the code object by subtler means than compiling a string, but that's not material to your question;-).
In older versions of Python you would have used the new module instead of the types module to make a new module object at the start, but new is deprecated since Python 2.6 and removed in Python 3.

Categories

Resources