先把有问题的代码晒一下:
IServer.py
from abc import ABCMeta, abstractmethod print __name__ class IServer: def __init__(self): pass @abstractmethod def DoWithA(self): pass @abstractmethod def DoWithB(self): pass
IServer_A.py
import IServer serverType ='1001' print __name__ dir() from CreatFactory import GLOBAL_class_dic dir() class IServer_A(IServer.IServer): def __init__(self): pass def DoWithA(self): print 'Server_A do with interface A' def DoWithB(self): print 'Server_A do with interface B' global GLOBAL_class_dic print 'the id of GLOBAL_class_dic in A is:',id(GLOBAL_class_dic) GLOBAL_class_dic[serverType] = IServer_A print 'GLOBAL_class_dic in a is:', GLOBAL_class_dic
IServer_B.py
import IServer serverType ='1002'from CreatFactory import GLOBAL_class_dic print __name__ class IServer_B(IServer.IServer): def __init__(self): pass def DoWithA(self): print 'Server_B do with interface A' def DoWithB(self): print 'Server_B do with interface B' print 'the id of GLOBAL_class_dic in B is:',id(GLOBAL_class_dic) GLOBAL_class_dic[serverType] = IServer_B print 'GLOBAL_class_dic in b is:', GLOBAL_class_dic
CreatFactory.py
#coding:UTF-8 import os; import sys; import threading from misc import * global GLOBAL_class_dic GLOBAL_class_dic ={1:1} print 'GLOBAL_class_dic in define is:', GLOBAL_class_dic print 'the id of GLOBAL_class_dic in define is:', id(GLOBAL_class_dic) dir() import IServer_A import IServer_B def CreateServer(serverType): global GLOBAL_class_dic print 'GLOBAL_class_dic in use is:', GLOBAL_class_dic print 'the id of GLOBAL_class_dic in USE is:', id(GLOBAL_class_dic) if GLOBAL_class_dic.has_key(serverType): return GLOBAL_class_dic[serverType] else: return 'no' if __name__ == '__main__': pass # 接收到报文后,根据报文的内容,从db中获取到serverType,假设获取到的serverType=1001 print 'main' print 'GLOBAL_class_dic in main A is:', GLOBAL_class_dic serverType = '1002' server = CreateServer(serverType) print 'GLOBAL_class_dic in main B is:', GLOBAL_class_dic print 'server :',server server.DoWithA(server())
代码内已经加了调试的部分信息, 运行CreatFactory.py。调用DoWithA失败,提示AttributeError: 'str' object has no attribute 'DoWithA'。运行结果如下:
D:\Python27\python.exe "D:/DesignMode/Server --00/CreatFactory.py" GLOBAL_class_dic in define is: {1: 1} the id of GLOBAL_class_dic in define is: 36230176 ['GLOBAL_class_dic', 'Misc', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'binascii', 'inspect', 'minidom', 'os', 'struct', 'sys', 'threading'] IServer IServer_A ['IServer', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'serverType'] GLOBAL_class_dic in define is: {1: 1} the id of GLOBAL_class_dic in define is: 36230032 ['GLOBAL_class_dic', 'Misc', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'binascii', 'inspect', 'minidom', 'os', 'struct', 'sys', 'threading'] ['IServer', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'serverType'] ['GLOBAL_class_dic', 'IServer', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'serverType'] IServer_B the id of GLOBAL_class_dic in B is: 36230032 GLOBAL_class_dic in b is: {1: 1, '1002': <class IServer_B.IServer_B at 0x022C2ED8>} ['GLOBAL_class_dic', 'IServer', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'serverType'] the id of GLOBAL_class_dic in A is: 36230032 GLOBAL_class_dic in a is: {1: 1, '1002': <class IServer_B.IServer_B at 0x022C2ED8>, '1001': <class IServer_A.IServer_A at 0x02273420>} main GLOBAL_class_dic in main A is: {1: 1} GLOBAL_class_dic in use is: {1: 1} the id of GLOBAL_class_dic in USE is: 36230176 GLOBAL_class_dic in main B is: {1: 1} server : no Traceback (most recent call last): File "D:/DesignMode/Server --00/CreatFactory.py", line 38, in <module> server.DoWithA(server()) AttributeError: 'str' object has no attribute 'DoWithA' Process finished with exit code 1
从运行的结果,可以看到:GLOBAL_class_dic 被定义了2次。有两个不同的id,第一次定义分配了一块内存,第二次不明原因的又重新分配了一块内存,然后服务的自动注册全部注册在这块内存中,等到main函数使用的使用,又使用的是第一次申请的内存,所以导致程序运行失败。那问题就来了,为什么会被重新又分配了一次?
之所以会被重新定义一次全局变量,是因为在执行CreatFactory.py时,最开始定义了全局变量,此时该命名空间可使用的函数和变量打印:['GLOBAL_class_dic', 'Misc', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'binascii', 'inspect', 'minidom', 'os', 'struct', 'sys', 'threading',然后在import IServer_A,在IServer_A.py中,import IServer后,在from CreatFactory import GLOBAL_class_dic打印出可使用的函数和变量时,['IServer', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'serverType'],就没有GLOBAL_class_dic,程序发现没有,就又重新声明了一遍。似乎问题原因已经找到了。
python在导入的时候,有2种场景,一种就是在文件前普通的import语句,还有一种就是特殊的场景:__main__模块是相对于Python的导入系统。在最开始运行CreatFactory.py文件时,__name__打印的值是__main__,而再子类再次导入时,会在当前命名空间查找是否已经导入__name__=CreatFactory,发现这个模块不存在,故此又导入了一遍,全局变量由此又被重新定义分配了内存,后期全局变量在子类业务的使用就都使用该值,而在main函数里,使用的又是当前的作用域内的第一次定义的全局变量。
问题内容: 我了解Python中局部变量和全局变量的概念,但是我只是有一个问题,为什么下面的代码中会出现错误?Python逐行执行代码,因此在读取第5行之前,它不知道a是局部变量。Python尝试执行第5行后,会回退一行并将其标记为错误吗? 问题答案: 设置和测试 为了分析您的问题,让我们创建两个独立的测试函数来复制您的问题: 版画。因此,调用此函数不是问题,而是在下一个函数上: 我们收到一个错误
问题内容: 此代码为何起作用: 但这给出了“分配前引用的局部变量’var’”错误: 问题答案: 因为在第一个代码中,您已经创建了一个局部变量并使用了它的值,而在第二个代码中,您正在使用局部变量,而没有对其进行定义。 因此,如果要使第二个功能正常工作,则需要声明:- 在使用该功能之前。 而在此代码中: 更新 :- 但是,按照@Tim的注释,您不应在函数内部使用变量。最好在使用变量之前先定义变量,然后
问题内容: 我正在Django中寻找一种简单但推荐的方式,将变量仅存储在内存中。当Apache重新启动或Django开发服务器重新启动时,该变量重置为0。更具体地说,我想计算在每个模型实例(数据库记录)上执行特定操作的次数,但是出于性能原因,我不这样做想要将这些计数存储在数据库中。我不在乎服务器重启后计数是否消失。但是,只要服务器启动,我就希望这些计数在Django Shell和Web界面之间保持
问题内容: 我正在尝试使用exec运行一段python代码。 这导致以下输出 但是,如果我将代码更改为此- 然后工作正常-提供以下输出- 显然,A存在并且可以访问-在第一段代码中出了什么问题?我正在使用2.6.5,欢呼声, 科林 更新1 如果我检查类中的locals()- 然后很明显,locals()在两个地方都不相同- 但是,如果我这样做,就没有问题- 更新2 好的,所以这里的文档-http:
本文向大家介绍Lua中全局变量与非全局环境介绍,包括了Lua中全局变量与非全局环境介绍的使用技巧和注意事项,需要的朋友参考一下 今天来聊两个话题——全局变量和非全局环境。 正如大家目前心里所感受到的,全局变量的内容很简单,而非全局环境的内容就稍微要锻炼一下脑细胞了。 1.全局变量的原形 在Lua中,要声明全局变量很简单,那就是定义变量的时候,前面不要加上local。 这个神秘的全局变量,其实本质上
主要内容:Python局部变量,Python全局变量,获取指定作用域范围中的变量所谓 作用域(Scope),就是变量的有效范围,就是变量可以在哪个范围以内使用。有些变量可以在整段代码的任意位置使用,有些变量只能在函数内部使用,有些变量只能在 for 循环内部使用。 变量的作用域由变量的定义位置决定,在不同位置定义的变量,它的作用域是不一样的。本节我们只讲解两种变量, 局部变量和 全局变量。 Python局部变量 在函数内部定义的变量,它的作用域也仅限于函数内部,出了函数就不能