33

オブジェクトが特定のモジュール内の任意のクラスのインスタンスであるかどうかを確認する方法が必要です。

そのモジュールからすべてのクラスを明示的にインポートし、タプルでチェックすることでそれができることを私は知っています:

from my_module import ClassOne, ClassTwo

>>> isinstance(my_obj, (ClassOne, ClassTwo))
True

しかし、実際には、私がインポートしているモジュールには大量のクラスが含まれており、それらをすべて明示的にインポートし、それらを使用して巨大なタプルを構築し、それに対して型チェックを行うのは不必要に冗長に思えます。これを回避するために、いくつかのことを試しました。

import my_module

# Test my_obj against the module itself
>>> isinstance(my_obj, my_module)
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

# Try to test against a wildcard attribute on my_module
>>> isinstance(my_obj, my_module.*)
SyntaxError: invalid syntax

#Try to build a tuple of clases with iteration to check against
>>> for klass in my_module:
TypeError: 'module' object is not iterable

タプルで明示的に名前を付けずに、my_module のすべてのクラスに対して型チェックを行う方法はありますか?

オプションの背景情報:
問題に対処するためのより良い方法を見落としている可能性があります。

Google App Engine アプリから、Rackspace でホストしているアプリにデータをエクスポートしています。でデータをシリアル化し、pickleHTTP リクエストで Rackspace サーバーに送信します。

Google App Engine データベース内の一部のデータは、google.appengine.api.datastore_types からインポートされた GAE 固有のデータ型です。これらのデータ型のいずれかが Rackspace サーバーに送信されると、Rackspace アプリに必要な GAE ライブラリがないため、depickling エラーが発生します。そのため、GAE から出る途中で、発信オブジェクトのいずれかに google.appengine.api.datastore_types のタイプがあるかどうかを確認しています。そうであれば、それらを組み込みのデータ型に変換するか、オブジェクトからフィールドを削除します。

4

2 に答える 2

21

inspect.getmembersモジュール内のすべてのクラスを取得するために使用できます。

inspect.getmembers(my_module,inspect.isclass)

これにより、名前とクラスのペアのリストが返されます。クラスが必要なだけです:

my_module_classes = tuple(x[1] for x in inspect.getmembers(my_module,inspect.isclass))

この回答を最初に書いたときに見落としていたものの 1 つは、クラスの__module__属性をチェックする機能です。__module__が期待どおりかどうかを確認することで回避できる場合があります。

from somewhere import module

if getattr(obj, '__module__', None) == module.__name__:
    # obj is from module.

isinstanceこれは、クラス名の大きなリストに対してチェックするよりも安価である可能性があります。

于 2013-01-28T20:41:57.927 に答える
2

@mgilsonの簡単なソリューションを使用しました:

from somewhere import module

if getattr(obj, '__module__', None) == module.__name__:
    # obj is from module.

モジュールのツリーがあり、それがベースモジュールからのものであることを確認したい場合は、次のことを行う必要があることに気付きました。

from somewhere import module

if getattr(obj, '__module__', None).split('.')[0] == module.__name__:
    # obj is from module.

ただしobject、組み込みの場合は例外が発生するため、次のようにします。

from somewhere import module

module_tree = getattr(obj, '__module__', None)
parent = module_tree.split('.')[0] if module_tree else None

if parent == module.__name__:
    # obj is from module.
于 2018-10-12T16:04:38.443 に答える