Search code examples
pythonpropertiesdecorator

How to assign custom names to properties?


I'm using a PLC shield (Kontron Pixtend) to read and control pneumatic valves and switches. A Python API (class) is provided. All runs on a Raspberry Pi. Outputs/inputs of the PLC shield are implemented using @property decorators:

class PiXtendV2L():
    ....
    @property
    def digital_in0(self):
        """
        Get the state of digital input 0. A value of False means 'off' and a value of True means 'on'.

        :return: Current value
        :rtype: bool
        """
        return self.test_bit(self._digital_in0, self.BIT_0) == 1

    @property
    def digital_in1(self):
        """
        Get the state of digital input 1. A value of False means 'off' and a value of True means 'on'.

        :return: Current value
        :rtype: bool
        """
        return self.test_bit(self._digital_in0, self.BIT_1) == 1

    @property
    def relay0(self):
        """
        Get or Set the state of relay 0. A value of False means 'off' and a value of True means 'on'.

        :return: Current value
        :rtype: bool
        """
        return self.test_bit(self._relay_out, self.BIT_0) == 1

    @relay0.setter
    def relay0(self, value):
        if value is False or value is True:
            pass
        else:
            raise ValueError("Value error!, Value " + str(value) + " not allowed! - Use only: False = off, True = on")

        bit_num = self.BIT_0
        if value is self.OFF:
            self._relay_out = self.clear_bit(self._relay_out, bit_num)
        if value is self.ON:
            self._relay_out = self.set_bit(self._relay_out, bit_num)
    ....

State of the relay is read accessing relay0 as variable, setting the relay by assigning True or False. I want to work with meaningful names:

self.p = PiXtendV2L(com_interval=0.05, callback=self.SPSCallback)
self.valve = self.p.relay0
self.switch = self.p.digital_in0

if self.switch:
    self.value = True
else:
    self.valve = False

I create self.valve and assign self.p.relay0. "relay0" is defined in PiXtendV2L class. But I cannot read state of the relay nor set it. It is not possible as the setter and getters are not accessed. I read the memory address of print(id(self.switch) and print(id(self.p.relay0)) and get the same address. How can this be done without much code? The alternative is use the names from the PLC's lib (digital_in0, relay0, digital_out0, etc.).


Solution

  • If you just want switch to be another name for relay0 in your class then just add switch = relay0 in your class somewhere after you've defined relay0.

    If you want switch to have a little bit more smarts.

    @property
    def switch(self):
         do whatever you want, including accessing self.relay0
         return result
    
    @switch.setter
    def switch(self, value):
        do whatever you want, including setting self.relay0