Variable scope outside classes

My text editor is optionally extensible through python plugins. This requires me to extend the classes and override its methods. The general structure is similar to the fragment below. Please note that the signature of the function is fixed.

ftp_client supposed to share instances of both classes.

 ftp_client = None class FtpFileCommand(sublime_plugin.TextCommand): def run(self, args): global ftp_client # does it reference the variable of the outer scope? self.ftp_client = ftplib.FTP('foo') # login and stuff class FtpFileEventListener(sublime_plugin.EventListener): def run(self, args): global ftp_client # same for this self.ftp_client.quit() # 

Both of these classes must have one common variable. What is the best practice for sharing variables?

Edit based on Madgar's answer:

FtpFileCommand.run is called first, initializes ftp_client and works like a charm. FtpFileEventListener.run is called later and may reference ftp_client , but it is still None . Using the global keyword, does it add the variable as a member to self ?

+6
source share
5 answers

Yes, that's how global works.

It seems to me that you are doing it right, as it is done in some modules of the python standard library ( fileinput , for example).

+5
source

In this code:

 global ftp_client # does it reference the variable of the outer scope? self.ftp_client = ftplib.FTP('foo') 

you declare ftp_client as a global variable. This means that it lives at the module level (where are your classes, for example).

The second line is incorrect. You want to assign a global variable, but instead you set an instance attribute with the same name.

It should be:

 global ftp_client ftp_client = ftplib.FTP('foo') 

But let me suggest a different approach. It is common practice to put such things inside a class, since it is shared by all instances of that class.

 class FtpFileCommand(sublime_plugin.TextCommand): ftp_client = None def run(self, args): FtpFileCommand.ftp_client = ftplib.FTP('foo') # login and stuff 

Note that the method does not use self , so it can also be a class method:

 class FtpFileCommand(sublime_plugin.TextCommand): ftp_client = None @classmethod def run(cls, args): cls.ftp_client = ftplib.FTP('foo') # login and stuff 

This way you get the class as the first argument, and you can use it to access the FTP client without using the class name.

+4
source

If there is only one common variable, then global is the easiest solution. But note that a variable should only be declared with global when assigned to it. If a global variable is an object, you can call its methods, change its attributes, etc., without declaring it global as global.

An alternative to using global variables is to use class attributes that are accessed using class methods. For instance:

 class FtpFile(object): _client = None @classmethod def client(cls): return cls._client @classmethod def setClient(cls, client): cls._client = client class FtpFileCommand(FtpFile, sublime_plugin.TextCommand): def run(self, args): client = self.client() class FtpFileEventListener(FtpFile, sublime_plugin.EventListener): def run(self, args): client = self.client() 
+3
source

Could you add a constructor for each class and then pass ftp_client as an argument?

 class FtpFileCommand(sublime_plugin.TextCommand): ... def __init__(self, ftp_client): self.ftp_client = ftp_client ... class FtpFileEventListener(sublime_plugin.EventListener): ... def __init__(self, ftp_client): self.ftp_client = ftp_client ... 
0
source

Yak ... THANK YOU SO THAT THIS !!!

You declare ftp_client as a global variable. This means that it lives in the module level (where are your classes, for example).

I had a difficult time trying to write my program โ€œcorrectlyโ€, where I use classes and functions and cannot name any of the variables. I recognized that global access to it will be available outside the class. When I read what I thought ... If it lives outside the class, then the variable that I need to get from the py script with which I import this module will be:

 module.variable 

And then in this module I declared another global variable to call it from the main script ... so an example ...

 #Main Script main.py import moduleA print(moduleA.moduleA.variable) #ModuleA code moduleA.py import moduleB class classA(): def functionA(): global moduleA_variable call.something.from.moduleB.classB.functionB() moduleA_variable = moduleB.moduleB_variable 

ModuleB code moduleB.py

 class classB(): def functionB(): global moduleB_variable moduleB_variable = retrieve.tacos() 

I hope my explanation also helps someone. I am new to Python and struggled with this for a while. In case this was not clear ... I had separate user modules consisting of several different .py files. The main one called module A, and module A called module B. I had to return the variable up the chain to the main script. What I am doing this like this was to keep the bulk of the script clean for the most part and tune in to doing repetitive tasks without having to write shit pages. Mostly trying to reuse functions instead of writing a book.

0
source

Source: https://habr.com/ru/post/899224/


All Articles