Accessing a python class variable defined inside the main script module

I have a django project that uses celery to handle async tasks. I am using python 2.7.

I have a class in a module client.py

in my django project:

# client.py
class Client:
    def __init__(self):
        # code for opening a persistent connection and saving the connection client in a class variable
        ...
        self.client = <connection client>

    def get_connection_client(self):
        return self.client

    def send_message(self, message):
        # --- Not the exact code but this is the function I need to access to for which I need access to the client variable---
        self.client.send(message)
    # Other functions that use the above method to send messages
    ...

      

This class only needs to be created once to create one persistent connection to the remote server .

I am running a script connection.py

that runs indefinitely:

# connection.py
from client import Client
if __name__ == '__main__':
    clientobj = Client()
    client = clientobj.get_connection_client()
    # Blocking process
    while True:
        # waits for a message from the remote server
        ...

      

I need to access a variable client

from another module tasks.py

(needed for celery).


# tasks.py
...
from client import Client
@app.task
def function():
    # Need access to the client variable
    # <??? How do I get an access to the client variable for the 
    # already established connection???>
    message = "Message to send to the server using the established connection"
    client.send_message(message)

      

All three python modules are on the same machine. connection.py

is executed as a standalone script and executed first. The method function()

in, tasks.py

if necessary, is requested several times by other modules of the project, so I cannot create an instance of the class client

inside this method. Global variables don't work.


In java we can create a global static variable and access it throughout the project. How do I do this in python?

Approaches I can think of, but not sure if they can be done in python:

  • Save this variable in a shared file so that it is available in other modules of my project?
  • Save this client as a parameter in django or celery and access that parameter in the required module?
  • Building on the suggestions of sebastian, another way is to exchange variables between running processes. I really want to do this. How do I do this in python?

For those wondering why this is required see this question . He explains the complete system design and the various components.

I am open to suggestions that also need to change the structure of the code.

+2


source to share


3 answers


multiprocessing

provides all the tools you need to do this.

connection.py

from multiprocessing.managers import BaseManager
from client import Client()
client = Client()
class ClientManager(BaseManager): pass
ClientManager.register('get_client', callable=lambda: client)
manager = ClientManager(address=('', 50000), authkey='abracadabra')
server = manager.get_server()
server.serve_forever()

      



tasks.py

from multiprocessing.managers import BaseManager
class ClientManager(BaseManager): pass
ClientManager.register('get_client')
manager = ClientManager(address=('localhost', 50000), authkey='abracadabra')
manager.connect()
client = manager.get_client()

@app.task
def function():
    message = "Message to send to the server using the established connection"
    client.send_message(message)

      

+2


source


I have no experience with django, but if they are executed from the same script, you can make the client a singleton request, or perhaps declare the client in init .py and then import wherever you need it.

If you go for singleton you can do a decorator for that:

def singleton(cls):
    instances = {}

    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return get_instance

      



Then you define:

# client.py

@singleton
class Client:
    def __init__(self):
        # code for opening a persistent connection and saving the connection client in a class variable
        ...
        self.client = <connection client>

    def get_connection_client(self):
        return self.client

      

That's all I can suggest, with the little description you provided. Perhaps try to explain a little better how things work, or the parts that are involved.

0


source


Python has class attributes (attributes that are shared by instances) and class methods (methods that act on the class itself). Both are readable by both the class and the instance.

# client.py
class Client(object):
    _client = None

    @classmethod
    def connect(cls):
        # dont do anything if already connected
        if cls._client is None:
            return

        # code for opening a persistent connection and saving the connection client in a class variable
        ...
        cls._client = <connection client>


    @classmethod
    def get_connection_client(cls):
        return cls._client


    def __init__(self):
        # make sure we try to have a connection on initialisation
        self.connect()

      

Now I am not sure if this is the best solution to your problem.

0


source







All Articles