-2

I reconstruct my code to more readable by using class and follow javascript style. The class is about modem device. In below I have 2 inner classes, SMS and Identify. For now it focuss on retrieve device informations. The problem it got error

'Identify' object has no attribute 'handle'

Inner class can't access outer attribute class.

import serial

class Device:
    def open(self, port, baudrate):
        self.handle = serial.Serial(port, baudrate)

    def readline(self):
        return self.handle.readline()

    def close(self):
        self.handle.close()

    class SMS:
        pass

    class Identify:
        def manufacturer(self):
             self.handle.write(b'AT+CGMI\r')

             while True:
                buffer = self.handle.readline()

                print(buffer)

                if buffer == b'OK\r\n':
                     break
                elif buffer == b'ERROR\r\n':
                    break

device = Device()
device.open('COM12', 9600)
device.Identify().manufacturer()
device.close()
David
  • 11
  • 4
  • 1
    Why *would* an Identify instance have a handle attribute? Where do you expect it to come from? Nesting isn't inheritance. – jonrsharpe Dec 01 '19 at 20:56
  • 4
    It is not appropriate to use "javascript style" in Python. Use Python style. Nested classes have very limited use in Python, and certainly not here. – Daniel Roseman Dec 01 '19 at 20:59
  • @Carcigenicate the reason is only more readable. Yes, i need to inherit `self.handle`. Thats the flow. – David Dec 01 '19 at 21:02
  • @DanielRoseman If so what your suggest to make the concept more readable in python? Class Identify needs handle from Class Device. – David Dec 01 '19 at 21:04
  • 2
    Your problem has nothing to do with readability. If you need access to it, then you need to use composition, not nesting. – Daniel Roseman Dec 01 '19 at 21:05
  • @Carcigenicate I try what u said. Pass outer class to inner class. But **name 'Device' is not defined** – David Dec 01 '19 at 21:12
  • @Carcigenicate I don't know what u means to making it a top level class. Can u answer it. – David Dec 01 '19 at 21:16
  • @DanielRoseman I would push back against the claim that what the op is doing is "JavaScript style" to begin with – juanpa.arrivillaga Dec 02 '19 at 01:39
  • Does this answer your question? [Inner Classes: How can I get the outer-class object at construction time?](https://stackoverflow.com/questions/2278426/inner-classes-how-can-i-get-the-outer-class-object-at-construction-time) – outis Dec 31 '21 at 10:07

1 Answers1

2

Identify doesn't inherit from Device just by being defined inside of it. If you want it to subclass Device, you need to explicitly write that:

class Identify(Device):
    . . .

The problem is though, a inner class can't inherit from an outer class. You'll need to make Identify a top level class along with Device.

class Device:
   . . .

class Identify(Device):
   . . .

If your intent was to make Identify slightly more hidden/indicate that it's an implementation detail, you could make it """private""" by giving the name a leading underscore:

class _Identify(Device):
   . . .

This doesn't actually prevent external access, but it does cause IDE warnings if it's imported or used externally, and causes it to be excluded from wildcard imports:

_single_leading_underscore: weak "internal use" indicator. E.g. from M import * does not import objects whose names start with an underscore.

Carcigenicate
  • 43,494
  • 9
  • 68
  • 117