Changing the definition of an existing function - python

I want to print to a file using print I import from __future___. I have the following as an import:
from __future__ import print_function
From now on, I can print using:
print("stuff", file=my_handle)
However, I have many calls to print in a function, so I would want to be able to use a function where the keyword argument is bound to my_handle. So, I use partial application:
printfile = partial(print, file=my_handle)
printfile("stuff")
printfile("more stuff")
which is what I intended. However, is there any way I can change to definition of print itself by partially applying the keyword argument? What I have tried was:
print = partial(print, file=my_handle)
however I got an error saying:
UnboundLocalError: local variable 'print' referenced before assignment
Is there any way to use print without mentioning my file every time?

print = partial(print, file=my_handle)
This line causes the UnboundLocalError on the second print, the one used as argument to partial(). This is because the name print is found to be a local variable in this particular function --- because you assign to it, in this case in the same line, more generally in the same function. You can't use the same variable name in one function to refer sometimes to a global and sometimes to a local.
To fix it you need to use a different name:
fprint = partial(print, file=my_handle).

Related

Scopes and Customizing Open (learning Python p. 539)

I'm a bit confused about a code in the book "Learning Python", p. 539.
As far as I know assignments within a function are only in this local scope. So if I want to change a global one I first have to declare it global. But why does the following code change the builtin.open() to custom completely once called?
import builtins
def makeopen(id):
original = builtins.open
def custom(*pargs, **kargs):
print('Custom open call %r: ' % id, pargs, kargs)
return original(*pargs, **kargs)
builtins.open = custom
If I call makeopen('spam') and a F = open('text.txt') afterwards I get the custom call. So the builtin.open() has been changed in the whole script after the makeopen('spam'). Why?
And if I would make some more makeopen('xx') one builtin.open('text.txt') would print the custom call for every created makeopen. Why?
Comparing this code to
x = 99
def changing():
x = 88
changing()
print(x)
doesnt even help me. Isn't it the same but with an x instead of builtin.open()?
A variable is considered local if you assign to it anywhere in the function, unless you declare it global.
In your first piece of code, you never assign anything to builtins, so it's not considered local. You just change one of its attributes, open.
The rule is respected!
In your second piece of code, you assign something to x in x = 88, so it is considered local.
When you call makeopen, you replace the original, global open with custom. custom, when executed, prints its name and calls the original open.
If you call makeopen a second time, it will create a second, different custom function, and make the name builtins.open refer to it. When you call this function, it will print its name, then call original, which is what builtins.open referred to when it was created - and that is your first custom function, which will print its name and call the original open.
So, successive calls to makeopen create a chain of functions, and calling open will make each of them run and call its predecessor.

Module with text files

I am very new to python, and am writing a code with multiple modules.
Each of my modules manipulates the same list that I have named "myList", however, I am having trouble understanding how to get the list into each module.
For example, one module called reverseList.py needs to take the list and reverse it, but when it is run in my main function, I get an error that the list does not exist.
Import reverseList
def main():
with open('list3.txt', 'r') as f:
data = f.read()
data = data.split("\n")
myList = [row.split(",") for row in data]
reverseList.reverse()
NameError: name 'myList' is not defined
The reverseList.py module is as follows:
def reverse()
myList1 = myList[::-1]
print(myList1)
return
It is unclear where exactly the error comes out since you didn't include your entire main function - there is no place myList is used before/after its definition. But I can think of a couple of reasons for the error.
The error shows up when a variable is used before it is defined. So, you might have the variable myList before you define it in line 4 of your current code.
In python, indentation is the matter of correctness of your code. Meaning, line 2~4 should be indented if you didn't do so.
I might be able to come up with a better answer if you present the rest part of the code.
Your update reveals where the problem is happening; that is from your reverseList, not your main.
You are loading myList in reverseList, but it has never been defined. myList defined in main is not accessible from reverseList. To fix this problem, you should pass myList as an argument to the function reverse when it is called and use that in your reverse function.
main:
reverseList.reverse(myList)
reverseList:
def reverse(myList):
myList1 = myList[::-1]
print(myList1)
return
Note that the argument name of the function reverse can be different from the one in main. In other words, it doesn't matter if you do follow;
def reverse(myList2):
myList1 = myList2[::-1]
print(myList1)
return
This might be better:
def reverse(myList2):
print(myList2[::-1])

Why does a function execute when put inside a variable (and how to stop it)

While writing a program in python i noticed that if one puts a function like print("hello world") inside a variable it will not be stored like expected, instead it will run. Also when i go and call the variable later in the program it will do nothing. can anyone tell me why this is and how to fix it?
If mean something like:
variable = print("hello world")`
then calling the function is the expected result. This syntax means to call the print function and assign the returned value to the variable. It's analogous to:
variable = input("Enter a name")
You're surely not surprised that this calls the input() function and assigns the string that the user entered to the variable.
If you want to store a function, you can use a lambda:
variable = lambda: print("hello world")
Then you can later do:
variable()
and it will print the message

how to declare variables in python in functions

I am newbie to python
i wrote a small function which is resulting in error
can you please let me know what is the mistake i am doing
def cost(input):
output=input*2
next=output*3
return output,next
print output
print next
Namerror name 'output' is not defined
Output is not defined since it is local to the function and the function hasn't even run. To get it globally, above print output you would put:
output, next = cost(1.12)
You need to call the function first. Both output and next are defined within the function and can not be accessed directly from outside.
print output
There is no variable called output for python to display. The output variable you have is inside the function, which is not accessible outside.
the problem is that the scope of the output and next variable is within the function, they cannot be referenced outside the function. If you want to print the result, just call the cost function in the print statement:
print cost(100)

Name Error when passing a parameter?

I am writing a program and keep on getting trouble with the error:
File "C:/Users//Documents///", line 47, in <module>
print(operations(sorted_list_desc))
NameError: name 'sorted_list_desc' is not defined
Even though you can not see the file I am working with, I have provided my code. I am supposed to loop the years and randomly choose an operator for each of the years. However, I keep on getting the error above. Any ideas why I keep on getting it?
import csv
#List to store different operators
list_operators = ["+","-","*","/"]
#Function to read file of list
def read_file():
#List to store data
sorted_list_desc = []
year = csv_file.readline()
population = csv_file.readline()
return sorted_list_desc
print(read_file())
def operations(sorted_list_desc):
for i in range(len(sorted_list_desc)):
operator = random.choice(list_operator)
return operator
print(operations(sorted_list_desc))
##
sorted_list_desc is generated by read_file(). Change your last line to:
print(operations(read_file()))
The line:
print(read_file())
does not magically created a global object withe name sorted_list_desc.
You need to hand it over explicitly to operations().
Alternatively, you could write:
sorted_list_desc = read_file()
print(operations(sorted_list_desc))
You have only assigned sorted_list_desc inside your function read_file(). Thus, your error is telling you that sorted_list_desc is not assigned to anything outside your function's scope. See Python scoping rules, and notice that you don't even need to pass sorted_list_desc as a parameter because it is assigned inside your function anyways.
Looks like sorted_list_desc is defined within the scope of your read_file() function and thus you can't reference it outside of that function. You can call print(operations(sorted_list_desc)) within 'read_file()', or you can define sorted_list_desc = [] at a global scope.

Categories

Resources