在创建其他文件中定义的其他类的对象时,无法访问python中的对象

时间:2015-04-16 13:28:49

标签: python class python-2.7 object python-import

我有一个像这样的目录结构:

home/
    main.py

    lib/
       mylib/
            Textfile_Class.py
            Excelfile_Class.py
            globals.py   (has all the global variables declared here)
            functions.py

我在Textfile_class中使用了main.py创建了一个对象 txt = TEXT(file)

现在,我想在为txt创建对象时使用此变量Excelfile_Class进行某些操作(例如,如果txt对象中的变量值为5,那么请确定Excelfile_Class )

中的操作

Excelfile_Class中,我还导入了所有全局变量。字符串变量可以在那里访问,但我不知道为什么这个对象txt在那里不可访问。无论我在txtExcelfile_Class)中引用self.line_count = txt.count,我都会收到以下错误:AttributeError: 'NoneType' object has no attribute 'count'

请帮助我知道为什么会发生这种情况,即使我已经在一个单独的文件中定义了所有变量并将其导入所有文件中。

例如: main.py

path = os.path.abspath('./lib')
sys.path.insert(0, path)

from mylib.Textfile_class import * 
from mylib.Excelfile_Class import *
from mylib.globals import *
from mylib.functions import *

if __name__ == "__main__":   
    txt = TEXT(file)
    xcel = EXCEL(file)

例如globals.py

global txt, xcel
txt=None
xcel=None

例如Textfile_class.py

from globals import *
class TEXT:
    def __init__(self, filename):
        self.count = 0
        with open(filename) as fp:
            for line in fp:
                self.count = self.count + 1`

例如Excelfile_Class.py

from globals import *

class EXCEL:
    def __init__(self, filename):
        self.line_count = 0
        self.operation(filename)

    def operation(self, file):
        self.line_count = txt.count 
        if self.line_count:
            self.some_operation()
        else:
            self.other_operation()

3 个答案:

答案 0 :(得分:2)

当您为函数内的变量名赋值时,您不再使用该变量的全局版本,而是拥有一个全新的变量。

您必须在函数内使用global关键字 来表明您正在使用全局变量。

来自Python Doc FAQ

  

Python中的局部变量和全局变量有哪些规则?

     

在Python中,仅在函数内引用的变量是隐式全局变量。如果在函数体内的任何位置为变量分配了一个新值,则假定它是一个局部变量。如果在函数内部为变量赋予了新值,则该变量隐式为局部变量,您需要将其显式声明为“全局”。

     

Read more...

示例:

x = None                # x is momdule-level global variable

def local():
    x = 5               # assign 5 to x, here x is a new variable, global x is not affected.

def glob():
    global x            # indicate we'll working with the global x.
    x = 5               # this affect the global variable.

def print_global():
    print(x)            # Just print the global variable.

local()                 
print_global()          # Prints None
glob()
print_global()          # Prints 5

因此,每次在函数内部引用txt时,您必须告诉您将使用txt的全局版本的上下文。

其他事情可能会发生!

Python被解释,这意味着它逐行执行代码,如果在其他模块(不在主模块中),您有代码试图在分配某个值之前访问txt

if __name__ == "__main__":   
    txt = TEXT(file)

,那么你会得到同样的错误。

建议:

尽量避免使用全局变量,你已经知道这不是一个好习惯,而且会导致代码不稳定。

如果您的问题是希望随时随地txtxcel可用,您可以使用模式Singleton (警告,Singleton被认为是反模式ref

我会为你发一个例子,但在我重新设计你的程序之前,我确保你这是一个很好的练习!

Singleton示例:(这也是一种反模式,但我将其置于裸体全局变量中)。

class Globals(object):

    __instance = None

    def __init__(self):

        class wrapped_class:
            def __init__(self):
                self.txt = None
                self.excel = None

        if (Globals.__instance is None):
            Globals.__instance = wrapped_class()

    def __getattr__(self, attrname):
        return getattr(self.__instance, attrname)

    def __setattr__(self, attrname, value):
        setattr(self.__instance, attrname, value)

glob = Globals()            # Since __instance is None this will instantiate wrapped_class and save the reference in __instance
glob.txt = "Txt example"    # Modify the txt attribute of __instance. 
glob_1 = Globals()          # Since __instance is not None it stays as it is.

print(glob.txt)             # Prints  "Txt example"
print(glob_1.txt)           # Prints  "Txt example"

答案 1 :(得分:1)

如果没有代码或堆栈跟踪,很难说出问题所在,但我强烈建议您阅读一些有关Python最佳实践,全局变量和命名约定的文档。这本身可能会解决您的问题。 命名约定可能听起来很愚蠢,但这些内容和其他与语法相关的选择在python中很重要。

此外,您似乎缺少模块中的__init__.py文件,根据您使用的python版本,该文件可能重要也可能不重要。

以下是一些可以帮助您入门的链接:

答案 2 :(得分:0)

我不知道为什么会这样。如果有人知道他们可以告诉你。

当我使用Using global variables between files in Python中给出的方法时问题得到了解决。

所以,最后我将所有全局变量放在globals.py的函数中,并在main.py中实例化一次。然后,我使用from mylib import globals并将类中的全局变量引用为globals.txt,它运行正常。