ted
ted

Reputation: 4985

Python achieve pointer like behaviour

I have to write a testing module and have c++-Background. That said, I am aware that there are no pointers in python but how do I achieve the following:

I have a test method which looks in pseudocode like this:

def check(self,obj,prop,value):
    if obj.prop <> value:  #this does not work, 
                           #getattr does not work either, (objects has no such method (interpreter output) 
                           #I am working with objects from InCyte's python interface
                           #the supplied findProp method does not do either (i get 
                           #None for objects I can access on the shell with obj.prop
                           #and yes I supply the method with a string 'prop'
        if self._autoadjust:
            print("Adjusting prop from x to y")
            obj.prop = value #setattr does not work, see above
        else:
            print("Warning Value != expected value for obj")

Since I want to check many different objects in separate functions I would like to be able to keep the check method in place.

In general, how do I ensure that a function affects the passed object and does not create a copy?

myobj.size=5
resize(myobj,10)
print myobj.size  #jython =python2.5 => print is not a function

I can't make resize a member method since the myobj implementation is out of reach, and I don't want to type myobj=resize(myobj, 10) everywhere

Also, how can I make it so that I can access those attributes in a function to which i pass the object and the attribute name?

Upvotes: 0

Views: 244

Answers (3)

Karl Knechtel
Karl Knechtel

Reputation: 61617

In general, how do I ensure that a function affects the passed object

By writing code inside the function that affects the passed-in object, instead of re-assigning to the name.

and does not create a copy?

A copy is never created unless you ask for one.

Python "variables" are names for things. They don't store objects; they refer to objects. However, unlike C++ references, they can be made to refer to something else.

When you write

def change(parameter):
    parameter = 42

x = 23
change(x)
# x is still 23

The reason x is still 23 is not because a copy was made, because a copy wasn't made. The reason is that, inside the function, parameter starts out as a name for the passed-in integer object 23, and then the line parameter = 42 causes parameter to stop being a name for 23, and start being a name for 42.

If you do

def change(parameter):
    parameter.append(42)

x = [23]
change(x)
# now x is [23, 42]

The passed-in parameter changes, because .append on a list changes the actual list object.

I can't make resize a member method since the myobj implementation is out of reach

That doesn't matter. When Python compiles, there is no type-checking step, and there is no step to look up the implementation of a method to insert the call. All of that is handled when the code actually runs. The code will get to the point myobj.resize(), look for a resize attribute of whatever object myobj currently refers to (after all, it can't know ahead of time even what kind of object it's dealing with; variables don't have types in Python but instead objects do), and attempt to call it (throwing the appropriate exceptions if (a) the object turns out not to have that attribute; (b) the attribute turns out not to actually be a method or other sort of function).

Also, how can I make it so that I can access those attributes in a function to which i pass the object and the attribute name? / getattr does not work either

Certainly it works if you use it properly. It is not a method; it is a built-in top-level function. Same thing with setattr.

Upvotes: 2

Stefano Borini
Stefano Borini

Reputation: 143865

In general how do I ensure that a function affects the passed object and does not create a copy?

Python is not C++, you never create copies unless you explicitly do so.

I cant make resize a member method since myobj implementation is out of reach, and I don't want to type myobj=resize(myobj,10) everywere

I don't get it? Why should be out of reach? if you have the instance, you can invoke its methods.

Upvotes: 2

John La Rooy
John La Rooy

Reputation: 304355

getattr isn't a method, you need to call it like this

getattr(obj, prop)

similarly setattr is called like this

setattr(obj, prop, value)

Upvotes: 5

Related Questions