繁体   English   中英

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

[英]Not able to access object in python while creating object of other class defined in some other file

我有这样的目录结构:

home/
    main.py

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

我使用txt = TEXT(file)main.py创建了Textfile_class对象。

现在,我想在创建Excelfile_Class对象期间使用此变量txt进行某些操作(例如,如果txt对象中的变量的值为5,则在Excelfile_Class )执行某些操作Excelfile_Class )

Excelfile_Class ,我还导入了所有全局变量。 字符串变量可在此处访问,但我不知道为什么该对象txt在此处不可访问。 无论我在Excelfile_Classself.line_count = txt.count )中Excelfile_Class 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()

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

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

从Python Doc常见问题解答

Python中局部和全局变量的规则是什么?

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

阅读更多...

例:

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

我将为您提供一个示例,但是在确保您重新设计程序之前,我确保您会做得很好!

单例示例:(再次这是一个反模式,但我将其设置为裸全局变量)。

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"

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

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

以下是一些入门指南:

我不知道为什么会这样。 如果有人知道,他们可以说出来。

当我使用在Python中的文件之间使用全局变量中给出的方法时,该问题得以解决。

因此,最后,我将所有全局变量放入globals.py中的函数中,并在globals.py实例化了该main.py 然后,我from mylib import globals使用了全局变量,并在类中将全局变量引用为globals.txt ,它可以正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM