Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?
On Thu, Feb 23, 2017 at 09:40:14PM +1100, Steven D'Aprano wrote: > How do instance attributes normally get set? In the __init__ method: > > class MyClass: > def __init__(self): > self.attribute = None > > > If the __init__ method does get run, it doesn't get the chance to create > the instance attributes. So if you have a subclass that defines > __init__, you need to allow the superclass' __init__ to run too. /me slaps forehead Of course I meant to write: If the __init__ method does NOT get run, it doesn't get the chance to create the instance attributes. Sorry for any confusion. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?
On Wed, Feb 22, 2017 at 10:49 PM, Zachary Warewrote: > On Wed, Feb 22, 2017 at 10:25 PM, boB Stepp wrote: > > I'll give you a couple of hints. First, try this: > > print('defining A') > class A: > print('Setting a on class A') When I typed this in I was surprised to find that the print() happens without having created an instance of this class yet. Further experimentation seems to indicate that all class methods and attributes get executed and assigned when the class definition is first read into the interpreter without any need to create an instance of the class. This is good to know! > Next, have a look at > https://docs.python.org/3/library/functions.html#super and in > particular the link at the end to Raymond Hettinger's "super > considered super" essay. I had actually bookmarked this last week in my browser for later reading. I just got finished reading it. It has brought additional clarity, but also much more I need to think about and explore. Thanks, Zach! -- boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?
Thank you to everyone that provided illumination in this thread! Things seem much clearer now, which caused me to realize that what I wrote below cannot work as written (Even though I did copy and paste it from the interpreter): On Wed, Feb 22, 2017 at 10:53 PM, boB Steppwrote: > On Wed, Feb 22, 2017 at 10:25 PM, boB Stepp wrote: >> I am trying to wrap my head around the mechanics of inheritance in >> Python 3. I thought that all attributes of a superclass were >> accessible to an instance of a subclass. But when I try the >> following: >> >> py3: class A: >> ... def __init__(self): >> ... self.aa = 'class A' >> ... >> py3: class B(A): >> ... def __init__(self): >> ... self.bb = 'class B' >> ... >> py3: a = A() >> py3: b = B() >> py3: b.aa >> Traceback (most recent call last): >> File "", line 1, in >> AttributeError: 'B' object has no attribute 'aa' >> >> I am unsuccessful... > > I have partially answered my own question, but I am not sure I > understand the mechanics yet. Apparently I must explicitly assign > class A's attribute, aa, to an instance of class B as follows: > > py3: class B(A): > ... def __init__(self): > ... self.aa = super().aa > ... self.bb = 'class B' > ... > py3: b = B() > py3: b.aa > 'class A' If I had copied and pasted the above two sections of code *contiguously*, this should have resulted in: py3: class B(A): ... def __init__(self): ... self.aa = super().aa ... self.bb = 'class B' ... py3: b = B() Traceback (most recent call last): File "", line 1, in File "", line 3, in __init__ AttributeError: 'super' object has no attribute 'aa' py3: a = A() py3: b = B() Traceback (most recent call last): File "", line 1, in File "", line 3, in __init__ AttributeError: 'super' object has no attribute 'aa' When I went back to scroll back in ConEmu (Thanks Eryk Sun for bringing this program to my attention!), I found that I had redefined class A as follows: py3: class A: ... aa = 'class A' ... between those two blocks of code, which explains why "b = B()" followed by "b.aa" worked. Sorry 'bout that! I did mention I was sleepy at the time... ~(:>)) -- boB ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Multiple muti-selection dropdown options
On 23/02/17 22:25, Pooja Bhalode wrote: > I am working on GUI where I have two dropdown menus in a Toplevel of the > main root. That's not what your code shows. It shows scrolling listboxes, not menus. But it seems like a Frame with a set of checkboxes would be closer to what you actually want? Anyway... > The window shows as below: > [image: Inline image 1] As I keep pointing out you cannot send images to this list, the server throws them away as potential security risks. > Whereas the code is: > > def selectexp(): > newlist = list() > selection = lstbox.curselection() > for i in selection: > tempvar = lstbox.get(i) > newlist.append(tempvar) > Note that in this function you create a list, populate it with values and then throw them all away. If you want to keep the values you need to declare the list as a global variable. > for val in newlist: > print (val) Because you are not posting in plain text I can't tell if those two lines are inside the previous function or not. I'm assuming they are inside the function? If not I'd expect a name error for newlist? > def selectexp2(): > newlist2 = list() > selection2 = lstbox2.curselection() > for i in selection2: > tempvar2 = lstbox2.get(i) > newlist2.append(tempvar2) > > for val in newlist2: > print (val) Same problem here, you declare newlist2 as a new list inside the function, then when the function exits it throws it away. If you want to access variables after the function exits you need to make them global (or start using classes and objects) > However, the issue is that when the user selects options from the first > dropdown menu and moves on to selecting the second one, the first dropdown > selections are lost, See comments above. Make the lists global. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Asking about Opening Teminal on Python
On 23/02/17 22:16, Quang nguyen wrote: > Hi everyone, > I need to open a terminal on Raspberry Pi 2 in order to execute codesend of > 433Utils to send a signal to RF Receiver. Anyone know how to open a > terminal? Do you really need a terminal? Or do you only need to execute some commands? In either case the subprocess module should do what you need. In the first case execute your local terminal program (eg xterm) In the second case execute the command you want directly via subprocess. This will be more efficient and save an extra terminal window popping up to distract your user. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Multiple muti-selection dropdown options
Hi, I am working on GUI where I have two dropdown menus in a Toplevel of the main root. Here, both the dropdown menus have mutiple selection option and thus, the selections can be taken as an input from the user and printed out in the code. The window shows as below: [image: Inline image 1] Whereas the code is: simroot = Toplevel(root) simroot.title("Simulation of experiments") Label(simroot, text = "Displaying concentration profiles with respect to time:").grid(row = 0, column = 0, sticky = W) Label(simroot, text = "Select the experiments to be displayed: ").grid(row = 1, column = 0, sticky = W) varlist = StringVar() varlist.set("Experiment1 Experiment2 Experiment3 Experiment4 Experiment5") scroll1 = Scrollbar(simroot, orient = "vertical") scroll1.grid(column = 2, sticky = W) lstbox = Listbox(simroot, listvariable = varlist, selectmode = MULTIPLE, yscrollcommand = scroll1.set, width = 20, height = 3) lstbox.grid(row = 2, column = 1, sticky = W) scroll1.config(command = lstbox.yview) def selectexp(): newlist = list() selection = lstbox.curselection() for i in selection: tempvar = lstbox.get(i) newlist.append(tempvar) for val in newlist: print (val) selectbutt = Button(simroot, text = "Submit", command = selectexp) selectbutt.grid(row = 6,column = 1, sticky = W) # Row 1 would print the name of the experiment selected and the species displayed would be in row3. Label(simroot, text = "Select concentration species:").grid(row = 7, column = 0, sticky = W) concvarlist = StringVar() concvarlist.set("A B C D E") scroll2 = Scrollbar(simroot, orient = "vertical") scroll2.grid(column = 2, sticky = W) lstbox2 = Listbox(simroot, listvariable = concvarlist, selectmode = MULTIPLE, yscrollcommand = scroll2.set, width = 20, height = 3) lstbox2.grid(row = 8, column = 1, sticky = W) scroll2.config(command = lstbox2.yview) def selectexp2(): newlist2 = list() selection2 = lstbox2.curselection() for i in selection2: tempvar2 = lstbox2.get(i) newlist2.append(tempvar2) for val in newlist2: print (val) selectbutt = Button(simroot, text = "Submit", command = selectexp2) selectbutt.grid(row = 9,column = 1, sticky = W) def Submitplot(): print "Create plot" Button(simroot, text = "Submit and Plot", command = Submitplot).grid(row = 10, column = 0, sticky = W) However, the issue is that when the user selects options from the first dropdown menu and moves on to selecting the second one, the first dropdown selections are lost, is there a way to store the highlighted selections on the display screen? In the code, I can get them printed and save the selections, however I was looking for a way to keep them highlighted on the screen as well for both the drop down menus. Please let me know. Thank you Pooja ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
[Tutor] Asking about Opening Teminal on Python
Hi everyone, I need to open a terminal on Raspberry Pi 2 in order to execute codesend of 433Utils to send a signal to RF Receiver. Anyone know how to open a terminal? Thank you. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?
On Wed, Feb 22, 2017 at 10:25:58PM -0600, boB Stepp wrote: > I am trying to wrap my head around the mechanics of inheritance in > Python 3. Here is a simplified picture of how inheritence usually works in Python. For an instance `spam`, when you look up an attribute (which includes methods), Python checks the following places *in this order*: - attributes attached to spam itself ("instance attributes"); - attributes attached to spam's class ("class attributes"); - attributes attached to any parent classes (class attributes of superclasses). (The actual rules are much more complex, but this will do for starters.) If no such attribute is found, Python will try calling the class __getattr__ (if any) or superclass __getattr__, and if that doesn't exist or fails, Python will raise AttributeError. How do class attributes normally get set? In the class definition: class MyClass: attribute = None How do instance attributes normally get set? In the __init__ method: class MyClass: def __init__(self): self.attribute = None If the __init__ method does get run, it doesn't get the chance to create the instance attributes. So if you have a subclass that defines __init__, you need to allow the superclass' __init__ to run too. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?
On 23/02/17 04:25, boB Stepp wrote: > I am trying to wrap my head around the mechanics of inheritance in > Python 3. I thought that all attributes of a superclass were > accessible to an instance of a subclass. For class attributes that happens automatically. >>> class A: a = 'A' def __init__(self): self.aa = 'aa' >>> class X(A): pass >>> x = X() >>> x.a 'A' >>> x.aa 'aa' Notice that both the class and instance variables are inherited. That's because there is no __init__() in X so the inherited A.__init__() is called. Now, if we add an init to the subclass: >>> class B(A): b = 'B' def __init__(self): self.bb='bb' >>> b = B() >>> b.a 'A' >>> b.bb 'bb' >>> b.aa Traceback (most recent call last): File "", line 1, in b.aa AttributeError: 'B' object has no attribute 'aa' We get the scenario you found. (But with the additional fact that B can access A's class variable 'a') The B.__init__() is called, but it does not create an aa instance variable. To do so we need to call the superclass constructor: >>> class C(A): c = 'C' def __init__(self): super().__init__() self.cc = 'cc' >>> c = C() >>> c.a 'A' >>> c.aa 'aa' >>> c.cc 'cc' >>> c.bb Traceback (most recent call last): File " ", line 1, in c.bb AttributeError: 'C' object has no attribute 'bb' >>> Now C can access cc and aa (as well as a), but not B.bb of course because its not in the inheritance line. There is no real magic(*) going on here. When you call SomeClass() the SomeClass.__new__() method gets called which is usually the one defined in object. That method results in __init__() getting called. The usual method lookup applies, the first init() found will be executed. If it doesn't explicitly call the superclass init then that method will never be called. (*)Actually its not quite this straightforward because meta-classes are involved in the invocation of new() and it all gets a bit mind-bending. But as a concept you can stick with new() as the constructor calling init() as the initializer and both being subject to the usual method resolution rules. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?
On Wed, Feb 22, 2017 at 10:25:58PM -0600, boB Stepp wrote: > I am trying to wrap my head around the mechanics of inheritance in > Python 3. I thought that all attributes of a superclass were > accessible to an instance of a subclass. But when I try the > following: > > py3: class A: > ... def __init__(self): > ... self.aa = 'class A' > ... There you have a class with an initializer method. And here you subclass it: > py3: class B(A): > ... def __init__(self): > ... self.bb = 'class B' > ... But you *override* the initialiser method and prevent the superclass' method from running. Only B's custom version will run. That's allowed, but fairly unusual. Normally you want to "overload" the method. Python can't guess if you want to call the superclass' version before or after your customization, so you have to decide for yourself: class B(A): def __init__(self): super().__init__() # call the superclass first self.bb = 'class B' super().__init__() # or last (Just don't do it twice, as I have! :-) In this specific instance, it doesn't matter whether you call super() first or last, but often it will. Welcome to the complexity of inheritence! And wait until you learn about multiple-inheritence, diamond diagrams, mixins, traits, and more. It's not *always* this complex. Often you subclass just to extend the class by adding a new method, and inheritence Just Works. You don't even have to think about it. But when overriding and overloading methods, you do have to think about what you are doing. -- Steve ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] How to access an instance variable of a superclass from an instance of the subclass?
boB Stepp wrote: > On Wed, Feb 22, 2017 at 10:25 PM, boB Stepp> wrote: >> I am trying to wrap my head around the mechanics of inheritance in >> Python 3. I thought that all attributes of a superclass were >> accessible to an instance of a subclass. But when I try the >> following: >> >> py3: class A: >> ... def __init__(self): >> ... self.aa = 'class A' >> ... >> py3: class B(A): >> ... def __init__(self): >> ... self.bb = 'class B' >> ... >> py3: a = A() >> py3: b = B() >> py3: b.aa >> Traceback (most recent call last): >> File "", line 1, in >> AttributeError: 'B' object has no attribute 'aa' >> >> I am unsuccessful... > > I have partially answered my own question, but I am not sure I > understand the mechanics yet. Apparently I must explicitly assign > class A's attribute, aa, to an instance of class B as follows: > > py3: class B(A): > ... def __init__(self): > ... self.aa = super().aa > ... self.bb = 'class B' > ... > py3: b = B() > py3: b.aa > 'class A' > > I was expecting that all of A's methods and attributes would > seamlessly be available to any instance of class B, but apparently > this is wrong-headed on my part. Instead, it looks like I need to > explicitly attach A's methods and attributes to B's instances via B's > self. > > I will continue to mull this over. You are making this harder than need be. If you have one class class A: def __init__(self): # complex calculation --> a self.a = a self.b = "whatever" you could split the code into two methods, to keep it manageable, say: class A: def __init__(self): self.init_a() self.b = "whatever" def init_a(self): # complex calculation self.a = a This will obviously continue to work with two classes: class A: def init_a(self): # complex calculation self.a = a class B(A): def __init__(self): self.init_a() self.b = "whatever" Now what if init_a() is actually called __init__? Just renaming will not work class A: def __init__(self): # complex ... self.a = a class B(A) def __init__(self): self.__init__() # this will invoke B.__init__ again # --> infinite recursion self.b = "whatever" so you either have to be explicit class B(A) def __init__(self): A.__init__(self) # this will invoke A.__init__ # because we told it to self.b = "whatever" or use "black magic" class B(A): def __init__(self): super().__init__() # have Python figure out # what to call self.b = "whatever" ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor