在python中允许多种类型的参数是一种好的实践吗

在python中允许多种类型的参数是一种好的实践吗,python,django,Python,Django,我在做一个django项目。在我正在编写的一个使用myModel实例的函数中,我考虑允许直接将该实例传递给函数,或者传递该实例的私钥,并进行查询以检索该实例: def myFunction(IdOrObj): myObj = myModel.objects.get(pk=IdOrObj) if isinstance(IdOrObj, int) else IdOrObj ... 这是坏习惯吗?如果是这样的话,原因是什么?有哪些替代方案?我发现这种方法往往会使代码相当难看。一旦您在

我在做一个django项目。在我正在编写的一个使用
myModel
实例的函数中,我考虑允许直接将该实例传递给函数,或者传递该实例的私钥,并进行查询以检索该实例:

def myFunction(IdOrObj):
    myObj = myModel.objects.get(pk=IdOrObj) if isinstance(IdOrObj, int) else IdOrObj
    ...

这是坏习惯吗?如果是这样的话,原因是什么?有哪些替代方案?

我发现这种方法往往会使代码相当难看。一旦您在多个位置开始执行此操作,您的许多功能将如下所示:

def myFunction(StrangeMetaObject):
    if isinstance(StrangeMetaObject, int):
        # Do the 
    elif isinstance(StrangeMetaObject, str):
        # Do the str thing...
    elif isinstance(StrangeMetaObject, MyObject):
        # ...
在某些情况下,调用代码希望传入看起来相同但不共享继承层次结构的任何部分的内容。例如,应允许:

class Person(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()

class Fox(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()

def print_age(IdOrObj):
    # This will fail if passed a Fox
    myObj = Person.objects.get(pk=IdOrObj) if isinstance(IdOrObj, int) else IdOrObj
    print('%s is %s years old' % (myObj.name, myObj.age))

对于您的用例,我建议您始终传递Django模型,很少有很好的理由使用IDs。

虽然这是可以接受的,但最好限制类型。例如,我只需执行
if-isinstance(IdOrObj,int)
,并检查
isinstance(IdOrObj,MyModel)
如果两个条件都不满足,则引发异常。嗯,是的,它可能很快就会变得混乱。