This question already has answers here:
Can a function have an attribute?
(2 answers)
Closed 1 year ago.
In the Python code portion of Inorder predecessor and successor for a given key in BST, something of this sort is done. Can someone explain this part of code?
P.S. I know what static variables are, it's just that its implementation in the way shown is confusing me.
# Static variables of the function findPreSuc
findPreSuc.pre = None
findPreSuc.suc = None
In Python, everything is object. And every object has member fields that can be accesed. This is stored in special field called __dict__. You can acces object attributes in various ways:
obj.field # direct attribute access
obj.__dict__["field"] # attribute dictionary access
getattr(obj, "field") # get attribute
Functions are objects too and thus they also have a __dict__ field. But they have unique behavior from other objects - if you try access field that doesn't exists with normal object, you will get error. If you try same thing with function, function will add new field instead (like how function create new local variables)
TL;DR: functions are objects too, and they can have fields like objects. These fields don't change between callings
Related
This question already has answers here:
How to get the original variable name of variable passed to a function [duplicate]
(13 answers)
Closed 7 years ago.
I'd like to be able to access the name of a variable that is passed to a function as e.g.
def f(x):
'''Returns name of list/dict variable passed to f'''
return magic(x)
>>a = [1,2,3]
>>print( f(a) )
'a'
>>print( f(2) )
None
I suspect this is possible using Python introspection but I don't know enough to understand the inspect module. (NB I know that the need for a function like magic() is questionable, but it is what I want.)
Actually, this is not possible. In Python names and values are quite separate. Inside f, you have access to the value of x, but it is not possible to find out what other names other functions might have given to that value.
Think of names as being somewhat like pointers in C. If you have a pointer, you can find out what object it points to. But if you have the object, you cannot find out what pointers are pointing to it.
This question already has answers here:
Does it make a difference using self for a temporary variable in a Python method?
(4 answers)
Closed 7 years ago.
Sorry, this is a really basic question, but I am just wondering when it is necessary to prepend self._ to variable declarations within methods? Every time I declare a variable within a method should I declare it with self._ included? Is there any situation where I should not do this?
Which of these methods would be valid for example (for some hypothetical class):
def thing_counter(self, thing):
length_of_thing = len(thing)
return length_of_thing
OR
def thing_counter(self, thing):
self._length_of_thing = len(thing)
return self._length_of_thing
Both work, but which would be strictly correct?
I know that a variable declaration is not really needed here, I am just trying to use a simple example.
Cheers!
Both work equally.
In the first version, length_of_thing will be created inside the function, and the return will return a copy to the caller. length_of_thing itself will not exist anymore after the return.
In the second one, self._length_of_thing will be created, not inside the function, but inside the instance of the class. The result is that it will be visible to all other methods. And the return still returns a copy.
So possibly this version uses a little more memory, as the variable self._length_of_thing remains alive till the instance of the class is destroyed.
This question already has answers here:
How to access (get or set) object attribute given string corresponding to name of that attribute
(3 answers)
Closed 8 years ago.
I'm writing a class in python that groups a bunch of similar variables together and then assembles them into a string. I'm hoping to avoid having to manually type out each variable in the generateString method, so I want to use something like:
for variable in dir(class):
if variable[:1] == '_':
recordString += variable
But currently it just returns a string that has all of the variable names. Is there a way to get at the value of the variable?
You can use the getattr() function to dynamically access attributes:
recordString += getattr(classobj, variable)
However, you probably do not want to use dir() here. dir() provides you with a list of attributes on the instance, class and base classes, while you appear to want to find only attributes found directly on the object.
You can use the vars() function instead, which returns a dictionary, letting you use items() to get both name and value:
for variable, value in vars(classobj).items():
if variable[:1] == '_':
recordString += value
I saw in a book about language description that says
On the other hand, a name can be bound to no object (a dangling pointer),
one object (the usual case), or several objects (a parameter name in a
recursive function).
How can we bind a name to several objects? Isnt that what we call an array for example where all elements have the same name but with index? For a recursive function like the example here:
x = 0
def f(y):
global x
x += 1
if x < 4 :
y +=100
f(y)
else: return
f(100)
Is the name y binded with multiple values that are created recursively since the nametable has already the y name binded to an initial value which is being reproduced with recursion?
EDITED Just press here Visualizer and see what it generates. :)
No.
A name is bound to one single object . When we are talking about Python - it is either bound to a single object in a given context, or do not exist at all.
What happens, is that the inner workings may have the name defined in several "layers" - but your code will only see one of those.
If a name is a variable in a recursive function, you will only see whatver is bound to it in the current running context - each time there is a function call in Python, the execution frame, which is an object which holds several attributes of the running code, including a reference to the local variables, is frozen. On the called function, a new execuciton frame is created, and there, the variable names are bound again to whatever new values they have in the called context. Your code just "see" this instance.
Then, there is the issue of global variables and builtin objects in Python: if a name is not a local variable in the function execution context, it is searched in the globals variables for the module (again, just one of those will be visible).ANd if the name is not defiend in the globals, them, Python looks for it in globals().__builtins__ that is your last call.
If I understand you correctly, you're asking about what rules Python has for creating variables in different scopes. Python uses lexical scoping on the function level.
It's hard to tell exactly what you're getting at with the code you've written, but, while there may be a different value associated with y in different scopes (with a value of y defined at each level of recursion), your code will only ever be able to see one at a time (the value defined at the scope in which you're operating).
To really understand scoping rules in Python, I would have a look at PEP 227. Also, have a look at this Stack Overflow question.
Finally, to be able to speak intelligently about what a "name" is in Python, I suggest you read about how Python is a "Call-By-Object" language.
At this point, we are capable of understanding that, instead of a "nametable", python uses a dictionary to hold what is accessible in a given scope. See this answer for a little more detail. The implication of this is that you can never have two of the same name in a single scope (for the same reason you can't have two of the same key in a python dictionary). So, while y may exist in a dictionary for a different scope, you have no way of accessing it, since you can only access the variables in the current scope's dictionary.
The key is:
several objects (a parameter name in a recursive function).
The passage is almost certainly not referring to arrays, but simply to the fact that in a recursive function (or any function, but a recursive function is likely to have multiple activations at one time), a parameter may be bound to a different value in each recursive call.
This does not mean that you can access each such object in every stack frame; indeed the point of the technique is to ensure that only one such value is accessible in each stack frame.
Firstly, you should mention in the question that the sentence from the book is not related explicitly to Python (as jsbueno wrote, one name is bound to exactly one object in Python).
Anyway, name bound to no object is a bit inaccurate. Generally, names are related to variables, and name related to a dangling pointer is the name of that pointer variable.
When speaking about the variable scope (i.e. the part of code where the variable is used), one variable name can be used only for a single value at a time. However, there may be other parts of code, independent on the one where we think about that variable. In the other part of code, the same name can be used; however, the two variables with the same name are totally isolated. This is the case of local variables also in the case of function bodies. If the language allows recursion, it must be capable to create another isolated space of local variable even for another call of the same function.
In Python, each function can also access outer variables, but it is more usual to use the inner, local variables. Whenever you assign a name some value, it is created in the local space.
I asked a previous question on stackoverflow here: Python immutable types in function calls
which made it clear that only references to immutable objects are passed to functions, and so passing a tuple to a function does not result in a full memory copy of that object.
However, according to: http://www.testingreflections.com/node/view/5126
"Some objects, like strings, tuples,
and numbers, are immutable. Altering
them inside a function/method will
create a new instance and the original
instance outside the function/method
is not changed."
I wrote some test code, where an immutable object is passed to a function. As expected, I can modify the object via the parameter-name/reference defined as part of the function header, and all changes only persist within the called function, leaving the original object outside of the function untouched.
So my question is:
Is the new instance created only when an attempt is made to alter/modify the object passed in? I'm guessing that if the object is not changed, a reference to it is all that is required. More importantly, if it does create a copy upon attempted modification, how does python manage the memory? With a zero-copy/copy-on-write, or does it create a complete replicated object (with the whole object's size reserved in memory) visible only within the called function?
You will think a lot more clearly about variables in Python if you think of them not as boxes that contain values, but names that are attached to objects. Any object can have any number of names attached to it; some of the names are local to functions and will be taken off the object automatically when the function returns.
So when you do something like this:
name = "Slartibartfast"
person = name
There is a string object, which contains the text "Slartibartfast", and there are two names by which it can be referred: name and person. You get the same object in both cases; you can verify this with the id() function.
Which is the "real" name of the string, name or person? This is a trick question. The string does not inherently have a name; it is just a string. name is not a box that contains "Slartibartfast", it is just an identifier that refers to the object. person has exactly the same standing in Python; name is not "more important" just because it was assigned first.
NOTE: Some objects, such as functions and classes, have a __name__ attribute that holds the name that was used to declare it in the def or class statement. This is the object's "real name" if it can be said to have one. However, you can still reference it through any number of assigned names.
Now, suppose you "modify" the string to give it a bit more of a Dutch flavor:
person = person.replace("art", "aart")
"Modify" is in quotes because you can't modify a string. Since a string is immutable, every string operation creates a new string. When does it happen? Immediately. In this case, the new string "Slaartibaartfast" is created and the name person is adjusted to refer to that. However, the name name still refers to the original string, because you haven't told it to refer to anything else. As long as at least one name refers to it, Python will keep good old "Slartibartfast" around.
This is no different when dealing with a function:
def dutchnametag(name):
name = name.replace("art", "aart")
print "HELLO! My Dutch name is", name
person = "Slartibartfast"
dutchnametag(person)
Here we assign the string "Slartibartfast" to the global name person. We then pass that string to our function, where it receives the additional local name name. The string's replace() method is then called through the name identifier, creating a new string. The identifier name is then reassigned to point to the new string. Outside the function, the global identifier person still refers to the original string, because nothing has changed it to point to anything else.
I'm not speaking about python per se. But generally, in immutable data structures, every method that you use that needs to change state will return a new object (with the modified state). The old one will remain the same.
For example, a Java mutable list could have:
void addItem(Object item) { ... }
the correspondent immutable List would have a method in the lines of
List addItem(Object item) { ... }
So, there is generally nothing special about immutable data structures. In any language you may create immutable data structures. But some languages make it hard or impossible to create mutable data structures (generally, functional languages).
Some languages may provide pseudo-immutable data structures. They make some special data structures look like immutable to the coder, while indeed they aren't.
If an object is immutable there is no way to change it. You could assign a new object to the name formerly associated with the argument object. To do this you first need to make a new object. So yes, you would allocate space for a complete new object.