简体   繁体   English

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

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

I have a directory structure like this: 我有这样的目录结构:

home/
    main.py

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

I created an object of Textfile_class in main.py using txt = TEXT(file) . 我使用txt = TEXT(file)main.py创建了Textfile_class对象。

Now, I want to use this variable txt during creating object of Excelfile_Class for some operations (eg, if the value of a variable in txt object is 5, then do certain action in Excelfile_Class ) 现在,我想在创建Excelfile_Class对象期间使用此变量txt进行某些操作(例如,如果txt对象中的变量的值为5,则在Excelfile_Class )执行某些操作Excelfile_Class )

In Excelfile_Class , I am also importing all the global variables. Excelfile_Class ,我还导入了所有全局变量。 String variables are accessible there but I dont know why this object txt is not accessible there. 字符串变量可在此处访问,但我不知道为什么该对象txt在此处不可访问。 Wherever I am refering to txt in Excelfile_Class ( self.line_count = txt.count ), I am getting below error: AttributeError: 'NoneType' object has no attribute 'count' 无论我在Excelfile_Classself.line_count = txt.count )中Excelfile_Class txtExcelfile_Class self.line_count = txt.count ,我都会遇到以下错误: AttributeError: 'NoneType' object has no attribute 'count'

Please help me to know why this is happening even though I have defined all the variables in a seperate file and importing those in all the files. 即使我已经在单独的文件中定义了所有变量并将其导入所有文件中,也请帮助我知道为什么会这样。

Eg: main.py 例如: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)

Eg globals.py 例如globals.py

global txt, xcel
txt=None
xcel=None

Eg Textfile_class.py 例如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`

Eg Excelfile_Class.py 例如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()

When you assign a value to a variable name inside a function, you're not working with the global version of the variable any more, instead you have a completely new variable. 当您在函数内部为变量名称分配值时,就不再使用该变量的全局版本,而是拥有一个全新的变量。

You have to use global keyword inside the function to indicate you're working with a global variable. 您必须在函数内部使用global关键字来指示您正在使用全局变量。

From Python Doc FAQ 从Python Doc常见问题解答

What are the rules for local and global variables in Python? Python中局部和全局变量的规则是什么?

In Python, variables that are only referenced inside a function are implicitly global. 在Python中,仅在函数内部引用的变量是隐式全局的。 If a variable is assigned a new value anywhere within the function's body, it's assumed to be a local. 如果在函数体内的任何位置为变量分配了新值,则假定该变量是局部变量。 If a variable is ever assigned a new value inside the function, the variable is implicitly local, and you need to explicitly declare it as 'global'. 如果在函数内部为变量分配了新值,则该变量是隐式局部变量,您需要将其显式声明为“ global”。

Read more... 阅读更多...

Example: 例:

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

So, every time you refer to txt inside a function, you have to tell the context you'll be working with the global version of txt . 因此,每次在函数中引用txt ,都必须告诉上下文您将使用txt的全局版本。

Other thing can be happening! 可能正在发生其他事情!

Python is interpreted, that means it execute the code line by line, if in the others modules (not in the main module) you have code trying to access txt before some value be assigned Python是经过解释的,这意味着它会逐行执行代码,如果在其他模块中(而不是在主模块中)您有在分配某些值之前尝试访问txt的代码

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

, then you'll get the same error. ,那么您将得到相同的错误。

A recommendation: 一条建议:

Try to avoid the use of global variables, you already know that isn't a good practice and it leads to unestable code. 尽量避免使用全局变量,您已经知道这不是一个好习惯,它会导致代码混乱。

If your problem is that you want to txt and xcel to be available at any time anywhere, you could use the pattern Singleton (warning, Singleton is considered an anti-pattern ref ) 如果您的问题是您想随时随地使用txtxcel ,则可以使用模式Singleton (警告,Singleton被视为反模式ref

I will post an example for you, but before I will encorage you to redesign your program, I ensure you it will be a good exercise! 我将为您提供一个示例,但是在确保您重新设计程序之前,我确保您会做得很好!

Singleton example: (again this is an anti-pattern, but I preffer it to nude global variables). 单例示例:(再次这是一个反模式,但我将其设置为裸全局变量)。

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"

It is quite hard to tell where your problem is without having the code or the stack trace but I would strongly advice that you read some documentation about Python best practices, the use of global variables and naming conventions. 如果没有代码或堆栈跟踪,很难说出问题出在哪里,但是我强烈建议您阅读一些有关Python最佳实践,全局变量和命名约定的文档。 This by itself might solve your issues. 这本身可以解决您的问题。 Naming conventions might sound silly but those things and other syntax-related choices do matter in python. 命名约定听起来很愚蠢,但是这些内容和其他与语法相关的选择在python中确实很重要。

Also, you seem to be missing __init__.py file in your module which may or may not be important depending of the python version you are using. 另外,您似乎在模块中缺少__init__.py文件,根据所使用的python版本,该文件可能重要也可能不重要。

Here are a few links to get you started: 以下是一些入门指南:

I dont know why it happened like that. 我不知道为什么会这样。 If anyone knows they can tell. 如果有人知道,他们可以说出来。

The problem got resolved when I used the method given in Using global variables between files in Python . 当我使用在Python中的文件之间使用全局变量中给出的方法时,该问题得以解决。

So, finally I put all the global variables in a function in globals.py and instantiated that once in main.py . 因此,最后,我将所有全局变量放入globals.py中的函数中,并在globals.py实例化了该main.py Then, I used from mylib import globals and referenced the global variables inside the classes as globals.txt and it worked fine. 然后,我from mylib import globals使用了全局变量,并在类中将全局变量引用为globals.txt ,它可以正常工作。

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

相关问题 将类中定义的对象访问其他类 - Access object defined in class to other class 在Python中的Thread类型的类中创建另一个类的对象时出错 - Error while creating an object of an other class in a class of type Thread in Python 创建 class 'list' 的新 object 和创建其他用户定义的 object 的 object 之间的区别 - difference between creating a new object of class 'list' and creating an object of other user defined class 从其他类访问类对象 - Access class object from other class 使用其他文件中定义的对象而不导入 - Using object defined in other file without importing 创建 python package 后,无法从另一个目录访问一个目录中的关键字 in.robot 文件 - Not able to access the keywords in .robot file in one directory from other directory after creating python package 属性化的 object 能否访问其对象在 python 中的其他属性? - Can an attributed object access its object's other attributes in python? 在对象实例上使用装饰器(或其他模式)来生成类 - Use a decorator (or some other pattern) on an object instance to generate a class 在其他程序在 python 中写入文件时读取文件 - Read a file while some other program is writing the file in python Python在读取文件时创建对象 - Python creating an Object while reading file
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM