From: Alan Harris-Reid on
Hi,

During my Python (3.1) programming I often find myself having to repeat
code such as...

class1.attr1 = 1
class1.attr2 = 2
class1.attr3 = 3
class1.attr4 = 4
etc.

Is there any way to achieve the same result without having to repeat the
class1 prefix? Before Python my previous main language was Visual
Foxpro, which had the syntax...

with class1
.attr1 = 1
.attr2 = 2
.attr3 = 3
.attr4 = 4
etc.
endwith

Is there any equivalent to this in Python?

Any help would be appreciated.

Alan Harris-Reid
From: Stefan Behnel on
Alan Harris-Reid, 20.04.2010 15:43:
> During my Python (3.1) programming I often find myself having to repeat
> code such as...
>
> class1.attr1 = 1
> class1.attr2 = 2
> class1.attr3 = 3
> class1.attr4 = 4
> etc.
>
> Is there any way to achieve the same result without having to repeat the
> class1 prefix? Before Python my previous main language was Visual
> Foxpro, which had the syntax...
>
> with class1
> .attr1 = 1
> .attr2 = 2
> .attr3 = 3
> .attr4 = 4
> etc.
> endwith
>
> Is there any equivalent to this in Python?

There's more than one way to do this, depending on your actual needs and
the source of the attributes. I assume this is done in __init__?

This might work for you:

self.__dict__.update(attr1=1, attr2=2, attr3=3, attr4=4)

You should also think once more about the use of the code you presented
above, having to set all those attributes may have a little smell. Maybe
that's totally ok, but since you mention that you "often" find yourself
doing the above, you may also have a mental design problem somewhere. We
can't tell unless you provide a more concrete example than what you show above.

Stefan

From: Iain King on
On Apr 20, 2:43 pm, Alan Harris-Reid <aharrisr...(a)googlemail.com>
wrote:
> Hi,
>
> During my Python (3.1) programming I often find myself having to repeat
> code such as...
>
> class1.attr1 = 1
> class1.attr2 = 2
> class1.attr3 = 3
> class1.attr4 = 4
> etc.
>
> Is there any way to achieve the same result without having to repeat the
> class1 prefix?  Before Python my previous main language was Visual
> Foxpro, which had the syntax...
>
> with class1
>    .attr1 = 1
>    .attr2 = 2
>    .attr3 = 3
>    .attr4 = 4
>    etc.
> endwith
>
> Is there any equivalent to this in Python?
>
> Any help would be appreciated.
>
> Alan Harris-Reid

The pythonic equivalent of VB 'with' is to assign to a short variable
name, for example '_':

_ = class1
_.attr1 = 1
_.attr2 = 2
_.attr3 = 3
_.attr4 = 4

alternatively, you could use the __setattr__ method:

for attr, value in (
('attr1', 1),
('attr2', 2),
('attr3', 3),
('attr4', 4)):
class1.__setattr__(attr, value)

and to get a bit crunchy, with this your specific example can be
written:

for i in xrange(1, 5):
class1.__setattr__('attr%d' % i, i)

Iain
From: Peter Otten on
Alan Harris-Reid wrote:

> Hi,
>
> During my Python (3.1) programming I often find myself having to repeat
> code such as...
>
> class1.attr1 = 1
> class1.attr2 = 2
> class1.attr3 = 3
> class1.attr4 = 4
> etc.
>
> Is there any way to achieve the same result without having to repeat the
> class1 prefix? Before Python my previous main language was Visual
> Foxpro, which had the syntax...
>
> with class1
> .attr1 = 1
> .attr2 = 2
> .attr3 = 3
> .attr4 = 4
> etc.
> endwith
>
> Is there any equivalent to this in Python?

No. You could write a helper function

>>> def update(obj, **kw):
.... for k, v in kw.items():
.... setattr(obj, k, v)
....

and then use keyword arguments:

>>> class A: pass
....
>>> a = A()
>>> update(a, foo=42, bar="yadda")
>>> a.foo, a.bar
(42, 'yadda')
>>>

But if you are doing that a lot and if the attributes are as uniform as
their names suggest you should rather use a Python dict than a custom class.

>>> d = {}
>>> d.update(foo=42, bar="whatever")
>>> d
{'foo': 42, 'bar': 'whatever'}
>>> d["bar"]
'whatever'

Peter
From: Alan Harris-Reid on
Jean-Michel Pichavant wrote:
> Alan Harris-Reid wrote:
>> Hi,
>>
>> During my Python (3.1) programming I often find myself having to
>> repeat code such as...
>>
>> class1.attr1 = 1
>> class1.attr2 = 2
>> class1.attr3 = 3
>> class1.attr4 = 4
>> etc.
>>
>> Is there any way to achieve the same result without having to repeat
>> the class1 prefix? Before Python my previous main language was
>> Visual Foxpro, which had the syntax...
>>
>> with class1
>> .attr1 = 1
>> .attr2 = 2
>> .attr3 = 3
>> .attr4 = 4
>> etc.
>> endwith
>>
>> Is there any equivalent to this in Python?
>>
>> Any help would be appreciated.
>>
>> Alan Harris-Reid
> Hello,
>
> Use an effective text editor, repeating stuff should not be a problem.
> In a more general manner, avoid trying to speed your writing while you
> should care speeding the reading.
> Most of the tricks you could use will confuse the reader (unless the
> reader is familiar with Visual foxpro).
>
> Anyway,
>
> for attrName, value in [
> ('attr1', 1),
> ('attr2', 2),
> ('attr3', 3),
> ]:
> setattr(class1, attrName, value)
>
> or
>
> class Foo:
> def __init__(self):
> self.attr1=None
> self.attr2=None
> self.attr3=None
>
> def set(self, *args, **kwargs):
> for k in kwargs:
> if hasattr(self, k):
> setattr(self, k, kwargs[k])
> else:
> raise AttributeError('%s instance has no attribute "%s"' %
> (self.__class__.__name__, k))
>
> f = Foo()
> f.set(attr1=25)
> print f.__dict__
> f.set(attr3=4, attr2=89)
> print f.__dict__
> f.set(bar= 8)
>
> output:
> {'attr2': None, 'attr3': None, 'attr1': 25}
> {'attr2': 89, 'attr3': 4, 'attr1': 25}
> AttributeError: Foo instance has no attribute "bar"
>
>
> JM
>
Hi Jean-Michel,

Interesting solutions, but I think for the effort involved (and
readability) I'll stick to repeating the class.

Regards,
Alan