简体   繁体   中英

Python access self of outer class from inner class

I trying to nest an inner class inside an outer class in Python to get a better structure when calling functions of the inner class.

So I have a python file with the following content which is called mvpSerial.py :

import struct
from numpy import uint32


class MVP:

    def __init__(self):
        self.__ser = self.__mvp_connect()
        return

    def __new__(cls):
        return super(MVP, cls).__new__(cls)

    def __mvp_connect(self):
        """Tries to connect to any
        connected prototype and return serial object"""
        print("Looking for MVP on all COM Ports....");
        # ...
        return serialObject

    def __evo_mvp_transfer(self, cmd, major=0, minor=0, data=0, tries=5):
        # do something with serial object of self
        # and return bytearray full of data
        self.__ser.write(data)
        return self.__ser.read(self.__ser.in_waiting)

    class cu(object):

        def pump_set_pwm(self, duty):
            self.outer.__evo_mvp_transfer(1, 24, 4, uint32(duty))

    class ic:
        def set_target_temperature(self, target):
            self.__evo_mvp_transfer(1, 36, 4, float(target))

I am importing this file in another one:

import mvpSerial

mvp = mvpSerial.MVP()

mvp.cu.pump_set_pwm(35)
mvp.ic.set_target_temperature(43)

In this file I want to create an instance of MVP class and call members of the nested function of cu and ic , because the physical MVP has two systems called CU and IC electrical connected to it.

So, instead of calling

mvp.cu_pump_set_pwm()

I want to divide the class 'mvp' into 'cu' and 'ic' to get a better and clearer structure of the real physical world and to write:

mvp.cu.pump_set_pwm()

But when I execute the code I get the following error:

Traceback (most recent call last):
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.3.3\plugins\python-ce\helpers\pydev\pydevd.py", line 1434, in _exec
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.3.3\plugins\python-ce\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "C:/Users/User/Documents/GitHub/qc-python/QC_main.py", line 11, in <module>
    mvp.cu.pump_set_pwm()
TypeError: pump_set_pwm() missing 1 required positional argument: 'self'

OO-languages are new for me, because up to now I only ever programmed C on microcontrollers. I doesn't need to be nested class, I just want to call function that belong to CU or IC over mvp.cu and mvp.ic instead of writing mvp.ic_set_target_temperature etc. to not have a bunch of function inside the MVP class.

Thanks in advance

I solved with the hint from chepner :

I split the class into four classes:

  • EvoSer: Does all the communication with serial sport
  • MVP: implements some functions that are used often by cu and ic
  • CU and IC classes for each system

MVP, CU and IC are child classes from EvoSer and therefore inheriting all functions from EvoSer:

class EvoSer:

    def __init__(self, ser=None):
        if ser is None:
            self.__ser = None
            self.mvp_connect()
        else:
            self.__ser = ser

    def __evo_mvp_transfer(self, cmd, major=0, minor=0, data=0, tries=5):
        # do something with serial object of self
        # and return bytearray full of data
        self.__ser.write(data)
        return self.__ser.read(self.__ser.in_waiting)

When a new instance of the class MVP is created it calls the init from EvoSer:

class MVP(EvoSer):

    def __init__(self):
        super().__init__()
        self.cu = CU(self._EvoSer__ser)
        self.ic = IC(self._EvoSer__ser)

    def __new__(cls):
        return super(MVP, cls).__new__(cls)

And also creates instances of CU and IC.

With this I am able to write:

import mvpSerial

mvp = mvpSerial.MVP()

mvp.cu.pump_set_pwm(35)
mvp.ic.set_target_temperature(43)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM