在 Python 中使用 type 作为字典键是否被视为良好实践?

Jin*_*Niu 0 python dictionary python-3.x

我有一个这样的查找表:

lookup = {
  "<class 'Minority.mixin'>": report_minority,
  "<class 'Majority.mixin'>": report_majority,
}

def report(o):
  h = lookup[str(type(o))]
  h()
Run Code Online (Sandbox Code Playgroud)

在我看来,这看起来很尴尬,因为与返回方式和代表in 的key方式存在不稳定的联系。如果有一天 Python 改变了表示类型的方式,那么所有这样的代码都会被破坏。所以想请教一下专业人士,这样的钥匙到底是好是坏?谢谢。type()classstringclassstring

Mar*_*ers 8

问题更在于你为什么要这样做认为使用字符串有什么优点?

类对象是可散列的,因此您可以直接Minority.mixin使用和作为键。当您这样做时,您可以确保密钥始终是完全相同的对象,前提是您的类在各自的模块中是全局变量,使它们成为您的程序的单例。此外,当您稍后重构代码以重命名模块时,不会出现意外混淆,并且最终会得到具有确切输出的不同类型。Majority.mixin repr()

因此,除非您有无法直接使用该类的特定用例,否则不应使用字符串表示形式。

(即使您要使用工厂函数生成类,使用基类并isinstance检查或从 MRO 中提取基类可能会更好)。

因此,对于您的用例,请坚持:

lookup = {
    Minority.mixin: report_minority,
    Majority.mixin: report_majority,
}

def report(o):
    h = lookup[type(o)])
    h()
Run Code Online (Sandbox Code Playgroud)

接下来,如果您确保 和report_minorityreport_majority函数例如,不是方法),则可以functools.singledispatch()完全使用和放弃映射:

from functools import singledispatch

@singledispatch
def report(o):
    raise ValueError('Unhandled type {}'.format(type(o)))

@report.register(Minority.mixin)
def report_minority(o):
    # handle a Minority instance

@report.register(Majority.mixin)
def report_majority(o):
    # handle a Majority instance
Run Code Online (Sandbox Code Playgroud)

请注意,这不适用于方法,因为方法必须采用多个参数才能进行调度,因为它们总是采用self.

单调度可以更好地处理子类str,这与基于 - 的映射甚至直接类映射不同。