Re: newbie: copy base class fields

2007-05-06 Thread tmp123
On May 3, 4:57 pm, "Jerry Hill" <[EMAIL PROTECTED]> wrote:
> Is it okay to copy them all at once?  Like this:
>
> class B(A):
> def __init__(self, a):
> self.__dict__.update(a.__dict__)
> self.v2 = 2
>

Thanks a lot for the answers, they seem to agree with the requested
funcitionality.

Kind regards.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: newbie: copy base class fields

2007-05-03 Thread Jerry Hill
On 3 May 2007 07:14:04 -0700, tmp123 <[EMAIL PROTECTED]> wrote:
> Of course, it is not an option to copy one by one all the fields of
> class A inside the __init__ of B.

Is it okay to copy them all at once?  Like this:

class B(A):
def __init__(self, a):
self.__dict__.update(a.__dict__)
self.v2 = 2

That will copy all of the attributes of instance a into the new instance.

-- 
Jerry
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: newbie: copy base class fields

2007-05-03 Thread Alex Martelli
tmp123 <[EMAIL PROTECTED]> wrote:
   ...
> It seems that the statement "self=a" is not the correct way to copy
> all the fields of the base class from the __init__ argument to the new
> object.

Indeed, it isn't.  Assigning to self just rebinds the name 'self' as a
local variable of method B.__init__ -- really useless.

> Of course, it is not an option to copy one by one all the fields of
> class A inside the __init__ of B.
> 
> Several variants of the program produces similar results.
> 
> Please, could someone explain which way is the correct way?

Somebody else suggested you call A.__init__ from inside B.__init__, and
that is correct if what you want to do is "freshly initialize the B
instance as an A".  However, from the fact that you pass to B.__init__
an argument 'a', it looks as if what you're trying to do is indeed copy
each of a's instance variables to self (it's hard to read your mind from
the code you've posted, but if I had to guess that would be by guess),
where a is an instance of A that's not necessarily "freshly
initialized".

In this case, you might for example start B.__init__ with:
self.__dict__.update(a.__dict__)

This is not very elegant or solid, but at least it's short and fast:-).

A better way would require having _somewhere_ a list or tuple with the
names of all the instance variables you know you want to copy; if that
list of names was for example B._names_to_copy,
for name in self._names_to_copy:
value = getattr(a, name)
setattr(self, name, value)
IS elegant and robust.  The advantages of explicitly controlling what
names you're copying (rather than blindly taking whatever happens to be
there) are similar to those of avoiding "from wherever import *": you
avoid accidental name pollution.  The advantages of using getattr and
setattr (rather than blindly working on the __dict__s) are those of
working correctly and transparently with properties and other similar
kinds of descriptors, rather than just "raw" instance variables.


Alex
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: newbie: copy base class fields

2007-05-03 Thread tmp123
On May 3, 4:29 pm, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote:
>
> > #!/usr/bin/python
> > #
>
> > class A:
> >   def __init__(self):
> > self.v1=1
>
> >   def __repr__(self):
> >  return "v1=%d\n" % self.v1
>
> > class B(A):
> >   def __init__(self,a):
> > self=a
> > self.v2=2
>
> >   def __repr__(self):
> >  return A.__repr__(self) + ("v2=%d\n" % self.v2)
>
> > x=A()
> > print x
>
> > y=B(x)
> > print y
>
> > $ ./prueba.pl
> > v1=1
>
> > Traceback (most recent call last):
> >   File "./prueba.pl", line 23, in 
> > print y
> >   File "./prueba.pl", line 17, in __repr__
> > return A.__repr__(self) + ("v2=%d\n" % self.v2)
> >   File "./prueba.pl", line 9, in __repr__
> > return "v1=%d\n" % self.v1
> > AttributeError: B instance has no attribute 'v1'
>


Hello Marc,

Thanks for your help.

I'm sorry, I've not correctly explained the subject. It is need to
init class B with the current value of the A instance, not with the
initial ones. A best example is:

x=A()
print x

x.v1=3

y=B(x)
print y

at the end, y.v1 must be equal to 3.

Sorry again.


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: newbie: copy base class fields

2007-05-03 Thread Marc 'BlackJack' Rintsch
In <[EMAIL PROTECTED]>, tmp123 wrote:

> The following small program gives an error:
> 
> #!/usr/bin/python
> #
> 
> class A:
>   def __init__(self):
> self.v1=1
> 
>   def __repr__(self):
>  return "v1=%d\n" % self.v1
> 
> class B(A):
>   def __init__(self,a):
> self=a
> self.v2=2
> 
>   def __repr__(self):
>  return A.__repr__(self) + ("v2=%d\n" % self.v2)
> 
> x=A()
> print x
> 
> y=B(x)
> print y
> 
> 
> 
> $ ./prueba.pl
> v1=1
> 
> Traceback (most recent call last):
>   File "./prueba.pl", line 23, in 
> print y
>   File "./prueba.pl", line 17, in __repr__
> return A.__repr__(self) + ("v2=%d\n" % self.v2)
>   File "./prueba.pl", line 9, in __repr__
> return "v1=%d\n" % self.v1
> AttributeError: B instance has no attribute 'v1'
> 
> 
> It seems that the statement "self=a" is not the correct way to copy
> all the fields of the base class from the __init__ argument to the new
> object.

This binds the local name `self` to the same object that is bound to `a`. 
Now you have lost the reference to the instance, so the next line sets the
attribute `v2` on the object passed to the constructor of the `B` object.

> Of course, it is not an option to copy one by one all the fields of
> class A inside the __init__ of B.
> 
> Several variants of the program produces similar results.
> 
> Please, could someone explain which way is the correct way?

Call the `__init__()` of `A`:

class B(A):
def __init__(self, a):
A.__init__(self)
self.v2 = 2

Ciao,
Marc 'BlackJack' Rintsch
-- 
http://mail.python.org/mailman/listinfo/python-list


newbie: copy base class fields

2007-05-03 Thread tmp123
Hello,

Thanks for your time.

The following small program gives an error:

#!/usr/bin/python
#

class A:
  def __init__(self):
self.v1=1

  def __repr__(self):
 return "v1=%d\n" % self.v1

class B(A):
  def __init__(self,a):
self=a
self.v2=2

  def __repr__(self):
 return A.__repr__(self) + ("v2=%d\n" % self.v2)

x=A()
print x

y=B(x)
print y



$ ./prueba.pl
v1=1

Traceback (most recent call last):
  File "./prueba.pl", line 23, in 
print y
  File "./prueba.pl", line 17, in __repr__
return A.__repr__(self) + ("v2=%d\n" % self.v2)
  File "./prueba.pl", line 9, in __repr__
return "v1=%d\n" % self.v1
AttributeError: B instance has no attribute 'v1'


It seems that the statement "self=a" is not the correct way to copy
all the fields of the base class from the __init__ argument to the new
object.

Of course, it is not an option to copy one by one all the fields of
class A inside the __init__ of B.

Several variants of the program produces similar results.

Please, could someone explain which way is the correct way?

Thanks a lot.

-- 
http://mail.python.org/mailman/listinfo/python-list