2

How to check if an object has been initialized in python?I have my_tac = tac(EDL_port) at multiple places ,in cases where it is already initialized it throws an error shown below..I want to add a check if my_tac is initiliazed or not,how to do that? CODE:-

#From another file
my_tac = tac(EDL_port)

#alpha.py
class tac:
   ## tac class constructor.
   #
   #  @param self
   #  @param timeout
   #  @param baud_rate
   def __init__(self, port=None, timeout=0.3, baud_rate=115200):
      if port is not None:
         self.port = port
         self.ser = serial.Serial(self.port, baud_rate, timeout=timeout)
         return
      else:
         (tac_ports,spider_ports) = tac_probe_for_devices()
         print "TAC ports..."
   ...................... 

ERROR:-

11/5/2016 8:54:05 PM: my_tac = tac(EDL_port)
11/5/2016 8:54:05 PM: File "C:\CST_QSPR\third_party_bin\BuildLoaderScripts\Android\android_dl\alpaca.py", line 90, in __init__
11/5/2016 8:54:05 PM: self.ser = serial.Serial(self.port, baud_rate, timeout=timeout)
11/5/2016 8:54:05 PM: File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 31, in __init__
11/5/2016 8:54:05 PM: ERROR:adb -s C2687475 remount failed
11/5/2016 8:54:05 PM: super(Serial, self).__init__(*args, **kwargs)
11/5/2016 8:54:05 PM: File "C:\Python27\lib\site-packages\serial\serialutil.py", line 236, in __init__
11/5/2016 8:54:05 PM: self.open()
11/5/2016 8:54:05 PM: File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 62, in open
11/5/2016 8:54:05 PM: raise SerialException("could not open port {!r}: {!r}".format(self.portstr, ctypes.WinError()))
11/5/2016 8:54:05 PM: serial.serialutil.SerialException: could not open port 'COM8': WindowsError(5, 'Access is denied.')
charlieW
  • 43
  • 1
  • 6
  • What do you mean by "initialized"? That `__init__()` is run? That is true for every object instance. Also how is the error message related to the question? – Klaus D. Nov 07 '16 at 04:09
  • Klaus - Question is how do I know if there is an object instance for my_tac already.... the error is related because every object initialization of my_tac holds a COM port ,say COM8 in this case...next time I initialize it throws an error `access denied....` – charlieW Nov 07 '16 at 04:15

4 Answers4

2

OP asked for it, OP receives it. This is an example of the singleton pattern, broken down to only one class.

class Test :
    count = 0
    def __init__(self, value) :
        if self.__class__.count > 0 :
            raise Exception
        else :
            self.__class__.count += 1
            self.value = value          #for the sake of the example


t1 = Test(12)      #instantiates the object
t2 = Test(27)      #throws an error

Tested with Python 3.4.3.

Right leg
  • 13,581
  • 5
  • 36
  • 68
1

What you looking here is called Singleton design pattern. The key idea of this method is that an object can be instantiated only once. The second time you try to instantiate it you will get the same object instead. It is handy for accessing databases or creating port handle as in your case. There is no really a way to make a singleton out of class in python. However you can convert your class into a module tac.py. Modules in python are singleton by default. For initialization your can define init(port=None, timeout=0.3, baud_rate=115200) function that will take any required parameters.

# tac.py

port = None

def init(myport=None, timeout=0.3, baud_rate=115200):
    if myport is not None:
       global port
       port = myport
       ser = serial.Serial(port, baud_rate, timeout=timeout)
       return
    else:
       tac_ports, spider_ports = tac_probe_for_devices()
       print "TAC ports..."

def tac_probe_for_devices():
    # Probe some devices
    pass

import tac
tac.init(8080)

# From another file
import tac
print 'Tac port: ', tac.port  # Print 8080

Please check this post for more implementation details.

Community
  • 1
  • 1
Kirill Kovalevskiy
  • 1,433
  • 2
  • 8
  • 6
  • Kiko - I need to pass the port from another file like below my_tac = tac(EDL_port),how would it change in such cases,in the example you showed you are initializing it in tac.py – charlieW Nov 07 '16 at 04:40
  • `import tac` `tac.init(8080)` – Kirill Kovalevskiy Nov 07 '16 at 04:43
  • You can use `import tac; tac.init(8080)` from another file. When you do `import tac` from third file it will return you the same instance. – Kirill Kovalevskiy Nov 07 '16 at 04:45
  • 1
    Actually, you can do this in a class, by defining your switch as a class variable. For instance, set `count` to zero inside of the class (but outside of any method!), and in the constructor, raise an exception if `count` is not zero, else initialize the object. – Right leg Nov 07 '16 at 04:51
  • Kiko - So,just to confirm,I should change `my_tac = tac(EDL_port)` to `my_tac = alpaca.init(EDL_port)` assuming the class tac: and initialization is in a file alpaca.py and its already imported in another file – charlieW Nov 07 '16 at 04:58
  • When you can do the same in `alpaca ` just bring your stuff outside the class and make it in `alpaca ` namespace. @Rightleg suggestion would also work if you still want to keep your class. – Kirill Kovalevskiy Nov 07 '16 at 05:08
  • @Rightleg - can you provide an example for your solution? – charlieW Nov 07 '16 at 05:45
0

There're multiple ways to solve this problem. But, I believe Singleton design pattern is the most elegant way to solve this problem.

For info. on how to implement Singleton design pattern, refer to following

Creating a singleton in Python

Community
  • 1
  • 1
Mangu Singh Rajpurohit
  • 8,894
  • 2
  • 50
  • 76
0

This is how you can set up a singleton class and pass your port to it. Just inherit your tac class from the SingletonClass. A trick here to make sure that you do not call __init__ twice. See how I check the return of super(self.__class__, self).__init__() to make sure it is not happening.

# tac.py

class SingletonClass(object):

    _inst = None
    _init_called = False

    def __new__(typ, *args, **kwargs):

        if SingletonClass._inst is None:
            obj = object.__new__(typ, *args, **kwargs)
            SingletonClass._inst = obj

        return SingletonClass._inst

    def __init__(self):

        # Call init inly on first instantiation if this class
        if SingletonClass._init_called:
            return True
        SingletonClass._init_called = True

class MyClass(SingletonClass):

    def __init__(self, port):

        if super(self.__class__, self).__init__():
            return

        self._port = port
        self._connections = '[D] Connection on port: %s' % self._port

    def connection(self):
        return self._connections

# From another file
from tac import MyClass

con = MyClass(8080)
print 'First connection id: ', id(con)
print con.connection()

con = MyClass(5000)
print 'Second connection id: ', id(con)
print con.connection()
Kirill Kovalevskiy
  • 1,433
  • 2
  • 8
  • 6