【问题标题】:Python - check for class existancePython - 检查类是否存在
【发布时间】:2016-11-05 09:22:27
【问题描述】:

有没有办法检查一个类是否已经定义/存在? 我在菜单上有不同的选项,其中一些需要继承变量,因此如果您在设置变量之前尝试选择该函数,它会崩溃。 我的课叫做 Gen0,我只是简单地把它开始了

class Gen0():

接下来是设置变量的其余代码。 对于上下文,我正在做一个人口模型,因此需要在显示(选项 2)、使用(选项 3)或导出(选项 4)之前设置初始值(选项 1)。

【问题讨论】:

  • Gen0是如何定义的?
  • 您可能可以使用 hasattr 内置函数来执行此操作,但更好的做法是在类的 __init__ 方法中始终初始化这些变量。
  • 在设置变量的选项的开头,它只是说 class Gen0():

标签: python class if-statement while-loop


【解决方案1】:

在 python 3.8 中你可以这样做:

class_name = "MyClass"
is_class_in_scope = globals().get(class_name) is not None

例子:

>>> from django.test import TestCase
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'TestCase': <class 'django.test.testcases.TestCase'>}
>>> globals().get('TestCase') is not None
True

【讨论】:

    【解决方案2】:

    最近我在编写自定义协议时遇到了同样的问题。这是我的解决方案,没有额外的模块,没有使用评估:

    import handlers
    
    # ... skip ...
    # create example request
    request = {'message': 'Test', 'param1': True, 'param2': False}
    
    Handler = getattr(handlers, '__dict__', {}).get(request.get('message'))
    if not Handler:
      raise InvalidRequestException('Invalid request')
    
    handler = Handler(request)
    # process request...
    
    # ... skip ...
    

    它不区分类/函数——你应该做一个额外的检查。

    【讨论】:

      【解决方案3】:

      您的情况并不完全清楚,所以我只是回答“有没有办法检查一个类是否已定义/存在?”的问题

      是的,有一些方法可以检查一个类是否已在当前范围内定义。我会经历一些。

      1。请求宽恕胜于允许

      尝试使用它!

      try:
          var = MyClass()
      except NameError:
          # name 'MyClass' is not defined
          ...
      

      这可能是最 Pythonic 的方法(除了确保您已导入/定义类之外)。

      2。查看当前范围

      当前范围内的所有内容都由dir() 给出。当然,这不会处理导入的东西! (除非它们是直接导入的。)

      if not 'MyClass' in dir():
          # your class is not defined in the current scope
          ...
      

      3。检查模块的内容

      也许您想查看该类是否定义在特定模块my_module 中。所以:

      import my_module
      import inspect
      
      if not 'MyClass' in inspect.getmembers(my_module):
          # 'MyClass' does not exist in 'my_module'
          ...
      

      现在,值得指出的是,如果您在任何时候在生产代码中使用这些类型的东西,您的代码可能写得不好。您应该始终知道在任何给定点哪些类在范围内。毕竟,这就是我们有 import 语句和定义的原因。我建议您使用更多示例代码清理您的问题,以获得更好的响应。

      【讨论】:

        【解决方案4】:

        我猜gen0 是这样定义的:

        class gen0:
            pass
        

        而不是在创建对象时初始化类中的属性

        class gen0:
            def __init__(self):
                # this function will be run when you call "g = gen0()"
                # in the main body of you code. and the following properties 
                # will be set on object "g"
                self.juvenile_population = 0
                self.juv.... etc
        

        所以我也猜想,当您在设置之前尝试访问 juvenile_population 之类的东西时,您会得到一个 AttributeError

        正确初始化您的类是进行面向对象编程恕我直言的最佳方式。

        但是,您的问题的字面答案是:

         g = gen0()
         if "juvenile_population" in dir(g):
              .... etc
        

        请注意,这仅检查对象是否具有 juvenile_population 属性,您需要更多这些语句来检查每个属性,同样您可以在 Douglas' answer 中使用 EAFP 方法,但同样会占用大量您的使用try 语句编写大量代码。

        【讨论】:

        • 如果我要正确初始化我的属性,我将如何检查类变量是否存在?有什么不同,还是只是初始化它们的好习惯?
        • 要么将它们设置为合理的默认值,例如 self.vari = None。然后你可以使用if g.vari: ....
        【解决方案5】:

        您可能想要寻找EAFP 解决方案,而不是检查变量是否存在。例如:

        try:
           print(var)
        except NameError:
           var = 2
           print(var)
        

        如果在这段代码之前没有定义var,它将分配给2print

        【讨论】:

        • try: class Display(Gen0): print(Gen0.juvenile_population) except NameError: pass this didn't work - 任何进一步的想法?
        • @ollie,你只在定义一个类时使用class关键字,而不是在你使用它的时候。我认为您应该多阅读一些有关语法的内容,否则您会因大量错误而感到非常沮丧。从这里开始:tutorialspoint.com/python/python_classes_objects.htm
        猜你喜欢
        • 2018-09-21
        • 2020-02-23
        • 2013-09-19
        • 2015-10-19
        • 2013-12-25
        • 2013-05-22
        • 2019-08-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多