简体   繁体   English

Python帮助:从另一个类访问静态成员变量

[英]Python Help: Accessing static member variable from another class

I'll do my best to describe the issue I am having. 我会尽力描述我遇到的问题。 I am building a Python program that is built on multiple classes and uses the unittest framework. 我正在构建一个基于多个类并使用unittest框架的Python程序。 In a nutshell, the Main.py file has a "ValidateDriver" class that defines a "driver" variable as an ElementTree type. 简而言之,Main.py文件具有一个“ ValidateDriver”类,该类将“ driver”变量定义为ElementTree类型。 If I point this directly to the XML file I need to parse, (ie driver = ElementTree.parse(rC:\\test.xml)) then I can access it from another class. 如果我直接将其指向需要解析的XML文件(即driver = ElementTree.parse(rC:\\ test.xml)),则可以从另一个类访问它。 However, in reality I don't have the actual XML file that is passed in from the command-line until you get to the Main function in the ValidateDriver class. 但是,实际上,直到进入ValidateDriver类中的Main函数,我才没有从命令行传递的实际XML文件。 So under the ValidateDriver class driver would really be driver = ElementTree and then in the main function I would reassign that variable to ValidateDriver.driver = ElementTree.parse(args.driver). 因此,在ValidateDriver类下,驱动程序实际上是driver = ElementTree,然后在主函数中将该变量重新分配给ValidateDriver.driver = ElementTree.parse(args.driver)。 However, this is the crux. 但是,这是症结所在。 When I go to the other class and try to call ValidateDriver.driver I don't have the "findall" method/attribute available. 当我去另一个课程并尝试调用ValidateDriver.driver时,我没有可用的“ findall”方法/属性。 Again, the only way it will work is to do something like: ElementTree.parse(rC:\\test.xml)). 同样,它将起作用的唯一方法是执行以下操作:ElementTree.parse(rC:\\ test.xml))。 If I did this in C# it would work, but I am new to Python and this is kicking my butt. 如果我用C#做到这一点就可以了,但是我对Python还是陌生的,这使我不寒而栗。 Any help/suggestions is appreciated. 任何帮助/建议表示赞赏。 I've included the code for both classes. 我已经包括了两个类的代码。

Main Function: 主功能:

import sys
import argparse
import xml.etree.ElementTree as ElementTree
import unittest
import Tests.TestManufacturer


class ValidateDriver:
    driver = ElementTree

    def main(argv):
        parser = argparse.ArgumentParser(description='Validation.')
        parser.add_argument('-d', '--driver', help='Path and file name xml file', required=True)
        parser.add_argument('-v', '--verbosity',
                            help='Verbosity for test output.  1 for terse, 2 for verbose.  Default is verbose',
                            default=2, type=int)
        #args = parser.parse_args()
        args = r'C:\test.c4i'
        #print ("Validate Driver: %s" % args.driver)
        #print ("Verbosity Level: %s" % args.verbosity)

        ValidateDriver.driver = ElementTree.parse(r'C:\test.c4i')

        loader = unittest.TestLoader()
        suite = loader.loadTestsFromModule(Tests.TestManufacturer)


        runner = unittest.TextTestRunner(verbosity=2) # TODO Remove this...
        # TODO Uncomment this...  
        runner = unittest.TextTestRunner(verbosity=args.verbosity)
        result = runner.run(suite)


    if __name__ == "__main__":
        main(sys.argv[1:])

Other Class, Test Manufacturer: 其他类,测试制造商:

import unittest
import Main


manufacturer = ['']


class Tests(unittest.TestCase):

    # Test to see if Manufacturer exists.
    def test_manufacturer_exists(self):
        for m in Main.ValidateDriver.driver.findall('./manufacturer'):
            print m.text

Producing the following error: 产生以下错误:

C:\Python27\python.exe C:\Users\test\PycharmProjects\Validator\Main.py
Traceback (most recent call last):
  File "C:\Users\test\PycharmProjects\Validator\Main.py", line 22, in <module>
    class ValidateDriver:
  File "C:\Users\test\PycharmProjects\Validator\Main.py", line 65, in ValidateDriver
    main(sys.argv[1:])
  File "C:\Users\test\PycharmProjects\Validator\Main.py", line 36, in main
    ValidateDriver.driver = ElementTree.parse(r'C:\test.c4i')
NameError: global name 'ValidateDriver' is not defined

Process finished with exit code 1

The main problem seems to be that your main script is wrapped in a class. 主要问题似乎是您的主脚本包装在一个类中。 There's really no reason for this, and is quite confusing. 确实没有任何理由,而且很令人困惑。

if __name__ == "__main__":
    main_object = ValidateDriver()
    main_object.main(sys.argv[1:])

This should go outside the class definition 这应该超出类定义

This has nothing to do with "findall" being available. 这与“ findall”可用无关。 The issue is that the class itself hasn't yet been completely declared at the time you try to access it. 问题在于,您尝试访问该类时尚未完全声明该类本身。 In python, the file is read top to bottom. 在python中,该文件是从上至下读取的。 For example, this is not allowed: 例如,不允许这样做:

if __name__ == "__main__":
    f()

def f():
    ...

The call to f must happen at the bottom of the file after it is declared. f的调用必须在声明后在文件的底部进行。

What you're doing with ValidateDriver is similar, because the class isn't defined until the statements directly in its body are executed (this is different from functions, whose bodies of course aren't executed until they are called). 您对ValidateDriver所做的操作是相似的,因为直到直接执行其主体中的语句才定义该类(这与函数(它们的主体当然要等到被调用后才执行)是不同的)。 You call main(sys.argv[1:]) inside the class body, which in turn tries to access ValidateDriver.driver , which doesn't exist yet. 您可以在类主体内调用main(sys.argv[1:]) ,而该主体又会尝试访问ValidateDriver.driver ,但尚不存在。

Preferably, the main function, as well as the code which calls it, should be outside the class. 最好, main功能以及调用它的代码应在类之外。 As far as I can tell, the class doesn't need to exist at all (this isn't C# or Java -- you can put code directly at the module level without a class container). 据我所知,该类根本不需要存在(这不是C#或Java-您可以将代码直接放在模块级别而无需类容器)。 If you insist on putting it in a class as a static method, it must be defined as a class method: 如果您坚持将其作为静态方法放入类中,则必须将其定义为类方法:

@classmethod
def main(cls, argv):
    ...

which can then be called (outside the class definition) like: 然后可以在类定义之外调用它,例如:

ValidateDriver.main(sys.argv[1:])

But I stress that this is non-standard and should not be necessary. 但是我强调这是非标准的,因此没有必要。

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

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