variable variables

S

someone

Hello,

is it possible to make first attr variable?

some_object.attr.attr

so instead of attr I could use self.foo which has value "attr"



Thanks!
 
S

someone

I think you're looking for getattr:http://docs.python.org/library/functions.html#getattr

name = "spam"
getattr(some_object, name) == some_object.spam == getattr(some_object,  
"spam")

Thanks.

I was looking for a "short way" to do it because I have a lot
"some_object.attr.attr or some_object.other_attr.attr" in code. it
looks like I cannot replace attr with just other variable and must
type some_object.other_attr.attr or your solution which is however
longer to type :)
 
L

Lie Ryan

Thanks.

I was looking for a "short way" to do it because I have a lot
"some_object.attr.attr or some_object.other_attr.attr" in code. it
looks like I cannot replace attr with just other variable and must
type some_object.other_attr.attr or your solution which is however
longer to type :)

Alternatively, if you have control over some_object class:

class SomeClass(object):
def __init__(self): pass
def __getattr__(self, attr):
return "attr: " + attr

some_object = SomeClass()

print some_object.foo
print some_object.myattr
 
J

James Mills

I was looking for a "short way" to do it because I have a lot
"some_object.attr.attr or some_object.other_attr.attr" in code. it
looks like I cannot replace attr with just other variable and must
type some_object.other_attr.attr or your solution which is however
longer to type :)

It would actually help to see some code.

--James
 
S

someone

It would actually help to see some code.

here it is, In Foo I'd like to have instead of A self.type and the
same in class B

from some_module import some_object

class Foo:
def __init__(self):
self.type = 'A'

def printAttr(self):
some_object.A.B
some_object.A.C
some_object.A.D
some_object.A.E
some_object.A.F
some_object.A.G

class Bar:
def __init__(self):
self.type = 'B'

def printAttr(self):
some_object.B.B
some_object.B.C
some_object.B.D
some_object.B.E
some_object.B.F
some_object.B.G
 
B

Bruno Desthuilliers

someone a écrit :
here it is, In Foo I'd like to have instead of A self.type and the
same in class B

from some_module import some_object

class Foo:
def __init__(self):
self.type = 'A'

def printAttr(self):
some_object.A.B
some_object.A.C
some_object.A.D
some_object.A.E
some_object.A.F
some_object.A.G

class Bar:
def __init__(self):
self.type = 'B'

def printAttr(self):
some_object.B.B
some_object.B.C
some_object.B.D
some_object.B.E
some_object.B.F
some_object.B.G


from some_module import some_object

def print_attributes(obj, *attribs):
for attr in attribs:
print getattr(obj, attr, None)

class Foo(object):
type = 'A'

def print_attr(self):
print_attributes(getattr(someobject, self.type), *"BCDEFG")

class Bar(Foo)
type = 'B'


Still has a "code smell" thing to me, but hard to say not knowing the
real code and context.
 
S

someone

someone a crit :












from some_module import some_object

def print_attributes(obj, *attribs):
   for attr in attribs:
     print getattr(obj, attr, None)

class Foo(object):
   type = 'A'

   def print_attr(self):
     print_attributes(getattr(someobject, self.type), *"BCDEFG")

class Bar(Foo)
   type = 'B'

Still has a "code smell" thing to me, but hard to say not knowing the
real code and context.

sorry, code is not about printing variables rather accessing, it's
just example.
 
B

Bruno Desthuilliers

someone a écrit :
On Jun 18, 2:05 pm, Bruno Desthuilliers <bruno.
(e-mail address removed)> wrote: (snip)

sorry, code is not about printing variables rather accessing, it's
just example.

Yeps, this I understood - hence the "but..." part of the sentence. What
I dislike the most here is the obj.otherobj.yetanother.attrib stuff -
might be ok in this case but it's an obvious violation of the law of
Demeter (=> AKA: only talk to your neighbour).

But anyway - if Foo only needs to know about someobject.A and Bar only
needs to know about someobject.B, then resolve them once:


from some_module import some_object

class Foo:
def __init__(self):
self.type = 'A'

def printAttr(self):
target = getattr(someobject, self.type)
target.B
target.C
target.D
# etc...


This will also save a couple useless lookups. In fact, aliasing a
commonly accessed attribute (or method) to a local name is an old time
Python micro-optimization.
 
S

someone

someone a crit :



Yeps, this I understood - hence the  "but..." part of the sentence. What
I dislike the most here is the obj.otherobj.yetanother.attrib stuff -
might be ok in this case but it's an obvious violation of the law of
Demeter (=> AKA: only talk to your neighbour).

But anyway - if Foo only needs to know about someobject.A and Bar only
needs to know about someobject.B, then resolve them once:

from some_module import some_object

class Foo:
     def __init__(self):
         self.type = 'A'

     def printAttr(self):
         target = getattr(someobject, self.type)
        target.B
         target.C
         target.D
         # etc...

This will also save a couple useless lookups. In fact, aliasing a
commonly accessed attribute (or method) to a local name is an old time
Python micro-optimization.

Thanks, this looks good. I've missed point that self.type must be an
instance of object and not just some string :)
 
J

Jean-Michel Pichavant

someone said:
here it is, In Foo I'd like to have instead of A self.type and the
same in class B

from some_module import some_object

class Foo:
def __init__(self):
self.type = 'A'

def printAttr(self):
some_object.A.B
some_object.A.C
some_object.A.D
some_object.A.E
some_object.A.F
some_object.A.G

class Bar:
def __init__(self):
self.type = 'B'

def printAttr(self):
some_object.B.B
some_object.B.C
some_object.B.D
some_object.B.E
some_object.B.F
some_object.B.G

Here is a way to to do it. Note that it is quite dangereous 'cause you
may confuse everyone by accessing some_object attributes like a Foo
attributes. Basically, when the attributes is not found in the Foo
namespace, it will use the some_object.A or some_object.B namespace instead.


some_object = Bar()
some_object.A = Bar()
some_object.B = Bar()
some_object.A.bar = 'I come from A'
some_object.B.bar = 'I come from B'

class Foo(object):

def __init__(self, _type):
self.type = _type

def __getattribute__(self, name):
try:
return object.__getattribute__(self, name)
except AttributeError:
return getattr(getattr(some_object, self.type), name)

def __setattr__(self, name, value):
try:
# first look if self has the attribute, if so set it
if object.__getattribute__(self, name):
return object.__setattr__(self, name, value)
except AttributeError:
# look into some_object
try:
_type = object.__getattribute__(self, 'type')
if hasattr(getattr(some_object, _type), name):
return setattr(getattr(some_object, _type), name, value)
except AttributeError:
pass
# attribute neither found in self nor in some_object, let's
create it in self
return object.__setattr__(self, name, value)

fa = Foo('A')
fb = Foo('B')

print fa.bar
> I come from A

print fb.bar
> I come from B

fa.bar = 'hello world'

print some_object.A.bar
> hello world



JM
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,474
Latest member
AntoniaDea

Latest Threads

Top