0

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?

6
  • 3
    Why do you use <> for non-equality? Nobody does that ... Commented May 14, 2012 at 10:59
  • @StefanoBorini: And as soon as they move to Python 3, they won't be able to do that anymore... Commented May 14, 2012 at 11:00
  • @StefanoBorini is != the way to go? Or shoudl I use another approach? I appreaciate the input that it might be outdated, but telling the right way as well would be nice so I can correct it Commented May 14, 2012 at 12:04
  • @Pomster: tried to write the check function (see semi-Pseudocode) however I obviously want the assignment obj.prop = value to affect the global scope, furthermore I need to run this check for different objects and different properties (can't hardcode eitherone, want to pass them seperately for better debugging, adjusted property on object is much clearer than Adjusted <str rep> to). However I can get the main part done now, since I know how to use getattr / setattr properly Commented May 14, 2012 at 12:09
  • In years of python programming, you are the first I see using <>. != is the non-equality operator, just like in C++ Commented May 14, 2012 at 12:16

3 Answers 3

5

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)
Sign up to request clarification or add additional context in comments.

2 Comments

i should read the docs more carefully, thank you. I assumed calling obj.func(2,3) == func(obj,2,3) which only holds for classes, and assumed that getattr was added by inheritance with class obj(object)
"only holds for classes" makes no sense. You're presumably thinking of objects, but in Python everything is an object. Including integers, classes themselves, functions, modules, you name it. The reason obj.getattr(prop) won't work is because getattr isn't an attribute of the obj in question. You certainly could define a method called getattr in your class (but you shouldn't), and they certainly could have made getattr a method of the base class object (but they didn't, and for good reasons, though partly historical).
2

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.

Comments

2

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.

2 Comments

yes I noticed my mistake with setattr after gnibbler pointed it out, but what if I don"t want the behaviour of paramter becoming a name for 42, but instead change the 42, the parameter from a different scope (not necessary global!) to change? without the parameter = change(parameter) hassle, is that possible in python?
on another note: well I still want myobj to be the cadence thing, setting it influences the program, its a provided interface which I can't replace.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.