Python isinstance(n, int)和int(n)==n的含义是什么?

3

两个功能:

def check(n):
    if int(n) != n:
        print("int(n) != n")
    else:
        print("int(n) == n")

并且

def check2(n):
    if not isinstance(n, int):
        print("n is not an int")
    else:
        print("n is an int")

有什么区别?哪一个更好?


3
它们完全做不同的事情,那么怎么可能有一个更好呢? - John La Rooy
看起来我发了一个愚蠢的问题。抱歉,大家。 - CodyChan
这不是一个愚蠢的问题。如果您不习惯于使用动态语言思考,那么n可以是Nonestr或几乎任何东西并不明显。也许只需要删除“哪一个更好?” - John La Rooy
是的,我没有注意到n可能是其他东西,比如“1”,或{}等。 - CodyChan
4个回答

3
第二个实际上可以工作(因为它没有在无法强制转换为整数的情况下出错),但这确实取决于你想做什么。如果你正在使用纯Python,最好的方法是鸭子类型——像这样的函数是对检查的微小调整,将检查某物是否为整数值(因此,例如,它将适用于2.02,但不是'2'),但不会出错:
def check3(n):
    "prints 'n is an int' if the value is integral"
    try:
        val = int(n)
        if val == n:
           print("n is an int")
    except ValueError:
        pass # return False would also work
    print("n is not an int")

相反,如果需要知道 1.01 之间的差异(例如,您有 int64 的 ndarray),则应使用您的实例检查 check2,因为它会让您知道它是 确切地 一个整数。
问题归结为这个问题:它必须是一个整数还是只能像整数一样行动?如果它必须是一个整数,则使用 check2,如果它必须 表现得 像一个整数,使用 check(但可能需要修改为在 try/except 中使用,如上所示)。
另一种选择是利用抽象基类来允许类似于整数的类型(例如,numpy 的整数 dtype,但不是 int 的子类),使用抽象基类 numbers.Integral
def check4(n):
    if isinstance(n, (int, numbers.Integral)):
        print("n is an int")
    else:
        print("n is not an int")

作为旁注,check4check3 慢得多,因为在抽象基类上进行实例检查的查找涉及一些处理。

2

你的第一个方法,if int(n) != n 是不好的。如果 n 不是字符串或数字,则转换为 int 将会引发异常:

>>> class Foo(object):
>>>    pass
>>> f = Foo()
>>> int(f)
TypeError: int() argument must be a string or a number, not 'Foo'

我相信在Python 2.x中最好的方法是:

if  isinstance(n, (int,long)):
    print 'n is an integer type'
else:
    print 'n is not an integer type'

请注意,我正在检查int long。这是因为isinstance(0xDEADBEEF2B84F00D, int) == False
此代码根本不处理浮点数值。由于您没有提供任何关于此代码将如何使用的信息,因此您需要正确处理所有情况。

2
主要区别在于,将输入转换为int时,如果输入不是基本数据类型,则会失败,而isinstance仅在输入类型为int或派生自int时才为True。因此,最好使用check2。请参考以下示例运行结果。
def check(n):
    if int(n) != n:
        print("int(n) != n")
    else:
        print("int(n) == n")

def check2(n):
    if not isinstance(n, int):
        print("n is not an int")
    else:
        print("n is an int")


class myInt(int):
    pass

check(1)
check("1")
#check({})      #Will throw error
#check([])      #Will throw error
check(myInt()) 
print ""
check2(1)
check2("1")
check2({})
check2(myInt())
check2([])

输出

int(n) == n
int(n) != n
int(n) == n

n is an int
n is not an int
n is not an int
n is an int
n is not an int

1
关于第一个问题,这两个函数回答了不同的问题。 check 查看 n 的数值并(有点)确定它是否有小数部分。 check2 查看类型并确定 n 是否为整数。 check 创建 n 的整数等价物,然后将其与 n 进行比较。因此,int(1.0)==1.0 为真,因为 int(1.0)==1,但 int("1")=="1" 为假,因为 int("1")==1check2 不进行任何转换,只是检查 n 的类型。

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