Python - 检查类是否存在

7

有没有一种方法可以检查类是否已定义/存在? 我在菜单上有不同的选项,其中一些选项需要继承变量,因此如果在设置变量之前选择该函数,则会崩溃。 我的类名为Gen0,我通过简单地放置它来开始。

class Gen0():

在设置变量的其余代码之后。 背景是,我正在进行人口模型,因此需要先设置初始值(选项1),然后在显示(选项2)或使用(选项3)或导出(选项4)它们之前。


Gen0类是如何定义的? - Resonance
你可能可以使用hasattr内置函数来实现这个,但更好的做法是在类的__init__方法中始终初始化这些变量。 - tobias_k
在设置变量选项的开始处,只是简单地写着 class Gen0(): - Ollie
5个回答

18

您的情况并不是很清楚,因此我只会回答“有没有一种方法可以检查类是否定义/存在?”这个问题。

是的,有几种方法可以检查当前范围内是否定义了一个类。我将介绍几种方法。

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'
    ...

现在,值得指出的是,如果您在生产代码中的任何时候使用这些东西,那么您可能正在编写糟糕的代码。 您应该始终知道哪些类在任何给定点上可用。 毕竟,这就是为什么我们有导入语句和定义的原因。 我建议您使用更多示例代码清理您的问题,以获得更好的回复。


0
最近在编写自定义协议时遇到了同样的问题。这是我的解决方案,没有使用任何额外的模块或eval函数:
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 ...

它不会区分类和函数 - 您需要进行额外的检查。


0

与其检查变量是否存在,你可能想要采用EAFP的解决方案。例如:

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

如果在这段代码之前没有定义变量var,它将把它赋值为2并将其print出来。

尝试: class Display(Gen0): print(Gen0.juvenile_population) except NameError: pass 这个没有起作用 - 有进一步的想法吗? - Ollie
1
@ollie,当你定义一个类时,只有在使用class关键字时才需要它。我认为你应该更多地了解语法,否则你会因为很多错误而感到非常沮丧。从这里开始:http://www.tutorialspoint.com/python/python_classes_objects.htm - Resonance

0

我猜测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属性,如果要检查每个属性,您需要更多的这些语句。同样地,您可以使用EAFP方法在Douglas' answer中,但是这将用try语句大量增加代码量。

如果我要正确初始化我的属性,那么我该如何检查类变量是否存在?这与其他方式有什么不同,还是只是良好的实践来初始化它们? - Ollie
可以将它们设置为合理的默认值,例如 self.vari = None。然后您可以使用 if g.vari: .... - Resonance

0
在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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接