0

Suppose I have the following:

class A: 

  def __init__( self, Att):
    """here Att is a string input"""
    self.Att = Att

  def __repr__( self ):
    s = "My attribute is " + self.Att 
    return s

class B: 

  def __init__( self, Btt):
    """here Btt is a string input"""
    self.Btt = Btt

  def __repr__( self ):
    s = "My other attribute is " + self.Btt 
    return s

  def SetEqual(self):
    Att = self.Btt 

I realize the SetEqual method above will not work. But how might I go about creating a method in class B that will access class A and change the value of self.Att to be equal to self.Btt?

fruitegg
  • 1
  • 2
  • It is unclear exactly what you want to accomplish, or even if that is something you should want to accomplish. – juanpa.arrivillaga Nov 18 '16 at 06:17
  • @Achilles, to my understanding that requires `class B` to be stated as follows: `class B(A):`. Is there a way to use inheritance without using `(A)` when first introducing `class B`? – fruitegg Nov 18 '16 at 06:18
  • So you want to pass an "A" into SetEqual, and set its Att property to whatever is in B's Btt property? – jeff carey Nov 18 '16 at 06:19
  • No.The whole idea about inheritance is a parent-child relationship. – Taufiq Rahman Nov 18 '16 at 06:22
  • @juanpa.arrivillaga, I wish to change the assignment of `self.att`, which is in `class A`, by using a method in `class B`. – fruitegg Nov 18 '16 at 06:22
  • @jeffcarey, yes. Sorry I noticed some ambiguity in my lower- and upper-case A's. It has since been edited. – fruitegg Nov 18 '16 at 06:24
  • @fruitegg I understand that, and the capitalization is not making it ambiguous. My point is that it is unclear what exactly you are trying to accomplish. It seems like you are under the impression that `att` belongs to `A`, but `att` is an instance attribute not a class attribute. – juanpa.arrivillaga Nov 18 '16 at 06:30

1 Answers1

0

The following method from B takes a A object and changes its value:

def setEqual(self, a):
    a.Att = self.Btt

Two remarks here.

First, Python does not know about encapsulation, so this is absolutely legal (and Pythonic) to write a.Att from the outside of the A class.

Second, be careful with the assignment, because it only links the two variables. As a tangible consequence, once you wrote a = b, a and b share the same id.

This is not a problem when manipulating immutable objects like integers, because if the two variables refer to the same id but one is modified, Python will change its id:

>>> a = 1
>>> b = a
>>> id(a) == id(b)
True
>>> b = 2
>>> id(a) == id(b)
False

However, when you manipulate collections, the behaviour is different:

>>> l1 = []
>>> l2 = l1
>>> id(l1) == id(l2)
True
>>> l1.append(12)
>>> id(l1) == id(l2)
True

Which means that when you manipulate mutable objects, changing its value somewhere will make it change everywhere else too.

You might want to take a look at the copy module for shallows and deep copies.

Right leg
  • 16,080
  • 7
  • 48
  • 81
  • Assignment doesn't make a shallow copy. – juanpa.arrivillaga Nov 18 '16 at 06:25
  • Yes it does. Try the following: `l1 = []` `l2 = l1` `l1.append(12)`. Now, both `l1` and `l2` are equal to `[12]`. That's what a shallow copy is. Linking here the question [What is the difference between a deep copy and a shallow copy?](http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy) – Right leg Nov 18 '16 at 06:37
  • Suppose instead that I wanted to solely reference the class A. Is it possible to change the value of `Att` by calling something like `A.self.Att = self.Btt` (not this exactly, of course, but something similar)? – fruitegg Nov 18 '16 at 06:39
  • No. Read what you linked to carefully: "A shallow copy of a collection is a copy of the collection structure, not the elements." Try `l1 = []` `l2 =l1` `id(l1) == id(l2)` or `l1 is l2`. It's not a copy at all. – juanpa.arrivillaga Nov 18 '16 at 06:41
  • @juanpa.arrivillaga I see your point. The outcome is the same though, but editing the answer – Right leg Nov 18 '16 at 06:46
  • @Rightleg No, the outcome is *not* the same as a shallow copy. Consider `x = [[],[]]` and check out `id(x)`. Now look at `print(*(id(sub) for sub in x))`. Now try `y = x.copy()` which *does* make a shallow copy (or `y = x[:]`, or `y = list(x)`). Then check out the output of `id(y)` (or for that matter, `x is y` and `id(x) == id(y)`). Now try `print(*(id(sub) for sub in y))` and note that while `y` is not the same object as `x`, but it contains the *same elements by identity*. That is what a shallow copy is. – juanpa.arrivillaga Nov 18 '16 at 06:48
  • @juanpa.arrivillaga Yes you're right, but that's not what I meant when I said the outcome was the same. I meant that in both cases, changing one object (or one of its sub-objects) somewhere might have some consequences elsewhere, when an assignment or a shallow copy was made, so the modifications should be made with caution. – Right leg Nov 18 '16 at 07:01
  • @juanpa.arrivillaga By the way, I agree I made a mistake about the shallow copy in my first comment – Right leg Nov 18 '16 at 07:04
  • @Rightleg Look at your original example. If a shallow copy were indeed made by assignment, then the behavior you describe with `l1` and `l2` would not hold. – juanpa.arrivillaga Nov 18 '16 at 07:05
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/128420/discussion-between-right-leg-and-juanpa-arrivillaga). – Right leg Nov 18 '16 at 07:06