This question already has answers here:
What does it mean when the parentheses are omitted from a function or method call?
(6 answers)
Closed 4 years ago.
So I got stuck on something like this (a simplified version)
class Node:
def __init__(self):
self.left= None
self.cost = 0
def change(self):
if self.left is not None:
self.left.cost=self.cost+1
self.left.change
data=[]
for i in range(10):
data.append(Node())
if i>0:
data[i].left = data[i-1]
data[8].change()
print(data[2].cost) #0
I want data[2].cost to have changed, but it rollbacks. Can I make it works without skipping recursion? (In full version I actually keep a two-dimensional array of nodes that have four pointers, so making an iteration suck.)
You forgot () when you call your change method.
def change(self):
if self.left is not None:
self.left.cost=self.cost+1
self.left.change()
output:
6
Obviously you want to call change but you didn't. You just refered to the function object and did nothing with it.
Just change self.left.change to self.left.change() to call it
Related
This question already has an answer here:
When running python files in terminal, do return commands not get executed?
(1 answer)
Closed 1 year ago.
I've spent more time than I should trying to solve a code problem this way:
class Rectangle:
def __init__(self, width, height):
self.w = width
self.h = height
def area(self):
# return area
return(self.w * self.h)
w = int(input())
h = int(input())
obj = Rectangle(w, h)
#call the function
obj.area()
I'm trying to call the area function like they call a function in this example:
class Dog:
def __init__(self, name, color):
self.name = name
self.color = color
def bark(self):
print("Woof!")
fido = Dog("Fido", "brown")
print(fido.name)
fido.bark()
But after giving up and looking at some answers and at a similar problem on a different site, people all use this instead:
print(obj.area())
Can somebody explain why I have to use print? It seems redundant but apparently it isn't, because without it, I get no output.
I think in order to help you understand the reason, it is important to understand the difference between a method that returns a value and one that has no return statement.
Firstly, ALL functions return a value. Even those that don't have an explicit return statement (such as your bark method). If no return statement is passed, the method returns value None. You can test this by doing:
print(fido.bark()) # prints None
Now in your area method you are returning a value, not printing it. That is why you have to print the value that gets returned in order to visualize it. That is the difference between the two methods. One returns the actual value, while the other one prints the value and returns None.
Hope that answers your question :) Cheers!
This question already has answers here:
Function closure vs. callable class
(6 answers)
Closed 2 years ago.
Is either of the two styles preferred or more "pythonic" for creating closures (edit: "closure-like objects")?
def make_doer(closed_var):
def doer(foo):
pass # Do something with closed_var and foo
return doer
class Doer:
def __init__(self, closed_var):
self._closed_var = closed_var
def __call__(self, foo):
pass # Do something with self._closed_var and foo
The only differences I can tell are that the former is a tiny bit shorter but the second has an advantage in that the docstring for the resulting function (__call__ in the second case) is less nested/hidden. Neither seems like a huge deal, anything else that would tip the balance?
Closures have to do with maintaining references to objects from scopes that have passed, or from earlier scopes.
Here is the simplest example of the form a Closure takes:
def outer():
x=7
def inner(y):
return x + y
return inner
i = outer()
This question already has answers here:
"Least Astonishment" and the Mutable Default Argument
(33 answers)
Closed 3 years ago.
I am implementing a basic node object in python. Basically, I implemented a node class with the attribute f_pointers and set it to the default value []. When ever I try to change f_pointers of (lets say) node_a, I will end up changing f_pointers of node_b, which are programmed to be completely unrelated.
I have already solved the problem by instead changing the default value to None and setting up the forward_pointers in __init__. However, I would still like to know how to avoid this problem in the future and possibly learn something new about Python.
For the sake of simplicity, I removed some unnecessary parts of the code.
class Node:
def __init__(self, f_pointers = []):
self.f_pointers = f_pointers
def get_pointers(self):
return self.f_pointers
def add_pointers(self, new_pointer):
self.f_pointers.append(new_pointer)
a = Node()
b = Node()
print(a.get_pointers, b.get_pointers)
>>> [] []
a.add_pointers("a")
print(a.get_pointers, b.get_pointers)
>> ["a"] ["a"]
a.add_pointers("b")
print(a.get_pointers, b.get_pointers)
>> ["a","b"] ["a","b"]
As can be seen, a and b are completely unrelated objects (other than the fact that they are of the same type Node) but will affect each other. Why does this happen?
It's because you are referencing to the same list (the one instantiated in the __init__ default params list definition like __init__(self, f_pointers=[]). What happens is that when you say in the __init__ method code block that self.f_points = f_pointers you are basically referencing the same list every time you instantiate a new Node object.
The reasons are explained further here
What you do want to do instead is instantiate a new list for every init like:
def __init__(self, f_pointers=None):
self.f_pointers = []
You should do it like this.
class Node:
def __init__(self, f_pointers=None):
if f_pointers:
self.f_pointers = f_pointers
else:
self.f_pointers = []
def get_pointers(self):
return self.f_pointers
def add_pointers(self, new_pointer):
self.f_pointers.append(new_pointer)
a = Node()
b = Node()
print(a.get_pointers(), b.get_pointers())
a.add_pointers("a")
print(a.get_pointers(), b.get_pointers())
You get this kind of behavior because in your case a.f_pointers and b.f_pointers is the same list, which was generated, when you described your class Node.
So a.f_pointers is b.f_pointers == True in your case
This question already has answers here:
"Least Astonishment" and the Mutable Default Argument
(33 answers)
Closed 4 years ago.
I was tring to build a trie tree base on a word list, below is the node class defintion, self.next_trees for children of the node.
class Node(object):
def __init__(self, charactor, tree_dict={}):
self.charactor = charactor
self.next_trees = tree_dict
self.is_end = False
and build the tree use this function
def build_tree(words):
root = Node(None)
for word in words:
trace = root.next_trees
for i,c in enumerate(word):
if c not in trace:
trace[c] = Node(charactor=c)
pdb.set_trace()
if i == len(word)-1:
trace[c].is_end = True
else:
trace = trace[c].next_trees
else:
trace = trace[c].next_trees
return root
each time when the codes run to the break point, the object "trace" refers to is exactly the same object "trace[c].next_trees" refer to,rather than a empty dict"{}" enter image description here
and I copy similiar codes to a new .py file and run, it won't happen again.why it happens here?(python version 2.7.12)
You are using a mutable object as a default variable (tree_dict={}). Try doing this instead:
def __init__(self, charactor, tree_dict=None):
if tree_dict is None:
tree_dict = {}
The default value of tree_dict ({}) is evaluated only when the __init__ method is constructed, not when it is called. This default value is then stored and reused for every future call to __init__. This then means that all instances of Node initialized with no explicit value of tree_node will use this stored object as its tree_node, meaning that when you modify one, you modify all others as well.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python code to get current function into a variable?
is there a convenient way to get to pointer of current function?
for example:
current_func_ref = None
def func():
current_func_ref = ___ #something need to fill
do something..
Ok this is a bit cheeky, not very generic like you might want, but here it is anyway:
current_func_ref = None
def func():
global current_func_ref
current_func_ref = func