我选择的文本编辑器可以通过python插件进行扩展。它需要我扩展类并覆盖它的方法。一般结构看起来类似于下面的代码段。请注意,函数签名是固定的。
ftp_client
应该由两个类的实例共享。
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() #
这两个类都应该有一个共同的变量。分享变量的最佳做法是什么?
基于madjars回答编辑:
FtpFileCommand.run
首先被调用,实现ftp_client
并且像魅力一样。 FtpFileEventListener.run
稍后会被调用,可以完美地引用ftp_client
,但它仍然是None
。使用global关键字,它是否将变量作为成员添加到self
?
答案 0 :(得分:5)
是的,这正是global
的工作方式。
在我看来,你做得对,因为它在python标准库的某些模块中以这种方式完成(例如,fileinput)。
答案 1 :(得分:4)
在此代码中:
global ftp_client # does it reference the variable of the outer scope?
self.ftp_client = ftplib.FTP('foo')
您将ftp_client
声明为全局变量。这意味着它存在于模块级别(例如,您的类所在的位置)。
第二行错了。您想要分配给全局变量,而是设置一个同名的实例属性。
应该是:
global ftp_client
ftp_client = ftplib.FTP('foo')
但是让我提出一个不同的方法。一种常见的做法是将这些东西放在类中,因为它由该类的所有实例共享。
class FtpFileCommand(sublime_plugin.TextCommand):
ftp_client = None
def run(self, args):
FtpFileCommand.ftp_client = ftplib.FTP('foo')
# login and stuff
请注意,该方法不使用self
,因此它也可能是一个类方法:
class FtpFileCommand(sublime_plugin.TextCommand):
ftp_client = None
@classmethod
def run(cls, args):
cls.ftp_client = ftplib.FTP('foo')
# login and stuff
这样您就可以将该类作为第一个参数,并且可以使用它来访问FTP客户端而不使用类名。
答案 2 :(得分:3)
如果只有一个共享变量,那么全局是最简单的解决方案。但请注意,变量只需在分配给global
时声明。如果全局变量是一个对象,则可以调用其方法,修改其属性等,而不必将其声明为全局变量。
使用全局变量的另一种方法是使用使用classmethods访问的类属性。例如:
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 :(得分:0)
您可以为每个类添加构造函数,然后将ftp_client
作为参数传递吗?
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
...
答案 4 :(得分:0)
牦牛......非常感谢你!
您将ftp_client声明为全局变量。这意味着它住在 模块级别(例如,您的类所在的位置)。
我正在努力编写我的程序"正确"我在哪里使用类和函数,不能调用任何变量。我认识到全球化将使它在课堂之外可用。当我读到我认为...如果它存在于类之外,那么我需要从py脚本中检索的变量我将从以下位置导入该模块:
module.variable
然后在该模块中,我声明了另一个全局变量来从主脚本中调用它...例如......
#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
class classB():
def functionB():
global moduleB_variable
moduleB_variable = retrieve.tacos()
我希望我的解释也有助于某人。我是python的初学者并且在这方面挣扎了一段时间。如果它不清楚......我有一些单独的自定义模块,由几个不同的.py文件组成。主要是调用moduleA而moduleA正在调用moduleB。我不得不将链中的变量返回到主脚本。我这样做的关键是保持主要脚本在大多数情况下是干净的,并且自己设置执行重复性任务而不必编写垃圾页面。基本上是尝试重用函数而不是写书。