类外的变量作用域
我选择的文本编辑器可以通过 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
中呢?
5 个回答
如果只有一个共享的变量,那么使用全局变量是最简单的解决办法。不过要注意,只有在给这个全局变量赋值的时候,才需要用到global
这个关键词。如果这个全局变量是一个对象,你可以直接调用它的方法,修改它的属性等等,而不需要先声明它为全局变量。
另外一种替代全局变量的方法是使用类属性,这些属性可以通过类方法来访问。例如:
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()
在这段代码中:
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 客户端,而不需要使用类名。
没错,这就是global
的工作方式。
我觉得你这样做是对的,因为在一些Python标准库的模块中也是这样做的(比如fileinput)。