python isinstance(n,int)和int(n)==n

python isinstance(n,int)和int(n)==n,python,Python,两个功能: def check(n): if int(n) != n: print("int(n) != n") else: print("int(n) == n") 及 有什么区别?哪一个更好?如果int(n)!=n不是一个好主意。如果n不是字符串或数字,则转换为int将失败,出现异常: >>> class Foo(object): >>> pass >>> f = Foo() >

两个功能:

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


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

如果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中)是:

请注意,我正在检查
int
long
。这是因为
isinstance(0xDEADBEEF2B84F00D,int)=False


这段代码根本不处理浮点值。您尚未向我们提供有关如何使用此代码的任何信息,因此您需要正确处理所有情况。

第二种方法实际上是有效的(因为它不会在某些不可强制为int的情况下出错),但它确实取决于您想做什么。如果您使用的是纯Python,最好的方法是duck类型-像这样的函数是对check的轻微调整,它将检查某个值是否为整数值(例如,它将使用
2.0
2
,但不是
'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.0
1
之间的区别很重要(例如,您有一个int64 ndarray),那么您应该使用实例检查
check2
,因为它会让您知道它正是一个int

它归结为一个问题:它必须是一个整数还是像一个整数?如果它必须是一个整数,那么使用check2,如果它必须像一个整数一样,那么使用check(但可能会将其修改为在try/except中,如上图所示)

另一种选择是利用抽象基类,使用抽象基类numbers.integral,允许int-like(例如,整数的numpy int数据类型,但实际上不是int的子类)

def check4(n):
    if isinstance(n, (int, numbers.Integral)):
        print("n is an int")
    else:
        print("n is not an int")

另一方面,
check4
比check3慢得多,因为对抽象基类的实例检查的查找需要一些处理。

主要区别是如果输入不是原始数据,那么将输入转换为
int
将失败,
isinstance
只有在输入类型为
int
或从中派生。
因此,最好使用
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

关于问题的第一部分,两个函数回答不同的问题。
check
查看
n
的数值,并(某种程度上)确定它是否有小数部分。
check2
查看类型并确定
n
是否为整数

  • check
    使整数等价于
    n
    ,然后将其与
    n
    进行比较。因此
    int(1.0)==1.0
    为真,因为
    int(1.0)==1
    ,而int(“1”)=“1”为假,因为
    int(“1”)==1

  • check2
    不进行任何转换,只是检查
    n
    的类型


他们做完全不同的事情,那么如何才能做得更好呢?似乎我发布了一个愚蠢的问题。对不起,伙计们。这不是一个愚蠢的问题。如果你不习惯用动态语言思考,
n
可以是
None
str
或几乎任何东西,这并不明显。也许只是删除“哪一个更好?”是的,我没有注意到n可以是其他的东西,比如“1”,或者{}等等。
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