在 Python 中,`is not int` 是否曾经 return false?
In Python, does `is not int` ever return false?
我正在使用参数解析器来允许将端口号传递给我的程序。然后我尝试验证该值,第一个测试是 is int
测试:
parser = argparse.ArgumentParser(description='Provides XML-RPC API.')
parser.add_argument('--port', dest='port', default=9666, type=int,
help='port to listen on, 9666 by default.');
args = parser.parse_args()
if args.port is not int:
raise TypeError("Port must be integer (%s given), use -h argument to get help."%(type(args.port).__name__))
if args.port>=65536 or args.port<=0:
raise IndexError("Port must be lower than 65536, 65535 is the maximum port number. Also, port can only be positive, non-zero number. Use -h argument to get help.")
if args.port<=1204:
print("Notice: ports up to 1024 are reserved to well known services, using this port numbers often leads to conflicts. Use -h argument to get help.")
现在无论我做什么,我都会收到错误消息:
Port must be integer (int given), use -h argument to get help.
我的意思是,到底是什么?连错误都说是int,这是怎么回事?
args.port is not int
将 return False
如果 args.port
曾经设置为 int
类型:
args.port = int
args.port is int # True
或者您将 int
重新绑定到同一对象 args.port
已经绑定到:
int = args.port
args.port is int # True
这是因为 is
测试两个引用是否指向完全相同的对象。
也许您对如何测试对象的类型感到困惑,因为您使用 isinstance()
function, or test the output of type()
:
type(args.port) is not int # False if args.port is a different type
not isinstance(args.port, int) # False if args.port is a different type and not a subclass either
也永远不会是这种情况,因为您将 ArgumentParser
选项配置为仅接受整数:
parser.add_argument('--port', dest='port', default=9666, type=int,
help='port to listen on, 9666 by default.')
type=int
参数很重要,因为这意味着任何不能解释为整数的东西都将被解析器拒绝。你永远不会超过 parser.parse_args()
这里:
>>> import argparse
>>> parser = argparse.ArgumentParser(description='Provides XML-RPC API.')
>>> parser.add_argument('--port', dest='port', default=9666, type=int,
... help='port to listen on, 9666 by default.')
_StoreAction(option_strings=['--port'], dest='port', nargs=None, const=None, default=9666, type=<type 'int'>, choices=None, help='port to listen on, 9666 by default.', metavar=None)
>>> parser.parse_args(['--port', 'not an integer'])
usage: [-h] [--port PORT]
: error: argument --port: invalid int value: 'not an integer'
那是因为'not an integer'
不能被int()
函数转换;引发 ValueError
并且 argparse
将其转换为错误消息:
>>> int('not an integer')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'not an integer'
您可以提供自己的限制范围的对话函数:
def portnumber(value):
port = int(value) # may raise ValueError
if not 0 <= port <= 65536:
raise ValueError('Not a valid port number')
return port
然后将其用作 type
:
parser.add_argument('--port', dest='port', default=9666, type=portnumber,
help='port to listen on, 9666 by default.')
一般来说,测试某物是否为 int
是由 isinstance(args.port, int)
完成的。但是,这里不需要此检查,因为 argparse 将保证它是您的整数。如果您没有指定默认值,None
也是可能的,但这里不是这种情况,因为您确实指定了默认值。
'int' 指的是 class 本身。如果您传递了 class 'int' 本身,'is not int' 将评估为 False,这不太可能发生。您可能需要 'isinstance( args.port, int)'。
is not int
将永远 return True
除非你 int is not int
。这是因为 is
是一个身份测试,这意味着它检查两个参数是否是同一个对象。
假设您尝试
>>> 1 is not int
这将 return True
因为 1
与 int
不是同一个对象。我们可以更深入地检查这一点。
>>> type(1)
<class 'int'>
如您所见,1
确实是一个 int
,但 int
本身实际上是 class。
要解决这个问题,您只需
not isinstance(args.port, int)
正如其他答案所建议的那样。
你也可以
type(args.port) is not int
检查 args.port
的类型是否为 int
.
我正在使用参数解析器来允许将端口号传递给我的程序。然后我尝试验证该值,第一个测试是 is int
测试:
parser = argparse.ArgumentParser(description='Provides XML-RPC API.')
parser.add_argument('--port', dest='port', default=9666, type=int,
help='port to listen on, 9666 by default.');
args = parser.parse_args()
if args.port is not int:
raise TypeError("Port must be integer (%s given), use -h argument to get help."%(type(args.port).__name__))
if args.port>=65536 or args.port<=0:
raise IndexError("Port must be lower than 65536, 65535 is the maximum port number. Also, port can only be positive, non-zero number. Use -h argument to get help.")
if args.port<=1204:
print("Notice: ports up to 1024 are reserved to well known services, using this port numbers often leads to conflicts. Use -h argument to get help.")
现在无论我做什么,我都会收到错误消息:
Port must be integer (int given), use -h argument to get help.
我的意思是,到底是什么?连错误都说是int,这是怎么回事?
args.port is not int
将 return False
如果 args.port
曾经设置为 int
类型:
args.port = int
args.port is int # True
或者您将 int
重新绑定到同一对象 args.port
已经绑定到:
int = args.port
args.port is int # True
这是因为 is
测试两个引用是否指向完全相同的对象。
也许您对如何测试对象的类型感到困惑,因为您使用 isinstance()
function, or test the output of type()
:
type(args.port) is not int # False if args.port is a different type
not isinstance(args.port, int) # False if args.port is a different type and not a subclass either
也永远不会是这种情况,因为您将 ArgumentParser
选项配置为仅接受整数:
parser.add_argument('--port', dest='port', default=9666, type=int,
help='port to listen on, 9666 by default.')
type=int
参数很重要,因为这意味着任何不能解释为整数的东西都将被解析器拒绝。你永远不会超过 parser.parse_args()
这里:
>>> import argparse
>>> parser = argparse.ArgumentParser(description='Provides XML-RPC API.')
>>> parser.add_argument('--port', dest='port', default=9666, type=int,
... help='port to listen on, 9666 by default.')
_StoreAction(option_strings=['--port'], dest='port', nargs=None, const=None, default=9666, type=<type 'int'>, choices=None, help='port to listen on, 9666 by default.', metavar=None)
>>> parser.parse_args(['--port', 'not an integer'])
usage: [-h] [--port PORT]
: error: argument --port: invalid int value: 'not an integer'
那是因为'not an integer'
不能被int()
函数转换;引发 ValueError
并且 argparse
将其转换为错误消息:
>>> int('not an integer')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'not an integer'
您可以提供自己的限制范围的对话函数:
def portnumber(value):
port = int(value) # may raise ValueError
if not 0 <= port <= 65536:
raise ValueError('Not a valid port number')
return port
然后将其用作 type
:
parser.add_argument('--port', dest='port', default=9666, type=portnumber,
help='port to listen on, 9666 by default.')
一般来说,测试某物是否为 int
是由 isinstance(args.port, int)
完成的。但是,这里不需要此检查,因为 argparse 将保证它是您的整数。如果您没有指定默认值,None
也是可能的,但这里不是这种情况,因为您确实指定了默认值。
'int' 指的是 class 本身。如果您传递了 class 'int' 本身,'is not int' 将评估为 False,这不太可能发生。您可能需要 'isinstance( args.port, int)'。
is not int
将永远 return True
除非你 int is not int
。这是因为 is
是一个身份测试,这意味着它检查两个参数是否是同一个对象。
假设您尝试
>>> 1 is not int
这将 return True
因为 1
与 int
不是同一个对象。我们可以更深入地检查这一点。
>>> type(1)
<class 'int'>
如您所见,1
确实是一个 int
,但 int
本身实际上是 class。
要解决这个问题,您只需
not isinstance(args.port, int)
正如其他答案所建议的那样。
你也可以
type(args.port) is not int
检查 args.port
的类型是否为 int
.