type(object)
一、学习内容概括:
学习地址:Python入门(上)
二、具体学习内容:
Python基础入门:从变量到异常处理。
三、学习问题和解决方法记录:
Q: 位运算实现快速计算和位运算实现整数集合比较陌生,想更透彻地了解一下。
A: 待添加
四、学习总结:
复习巩固了以前学到的知识。
a = 1031
print(a, type(a))
# 1031
Python 里面万物皆对象(object),整型也不例外,只要是对象,就有相应的属性 (attributes) 和方法(methods)。
print(1, type(1))
# 1
print(1., type(1.))
# 1.0
a = 0.00000023
b = 2.3e-7
print(a) # 2.3e-07
print(b) # 2.3e-07
有时候我们想保留浮点型的小数点后 n
位。可以用 decimal
包里的 Decimal
对象和 getcontext()
方法来实现。
import decimal
from decimal import Decimal
可以用上面提到的dir(decimal)
来看其属性和方法。
【例子】getcontext()
显示了 Decimal
对象的默认精度值是 28
位 (prec=28)。
a = decimal.getcontext()
print(a)
# Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999,
# capitals=1, clamp=0, flags=[],
# traps=[InvalidOperation, DivisionByZero, Overflow])
b = Decimal(1) / Decimal(3)
print(b)
# 0.3333333333333333333333333333
【例子】使 1/3
保留 4
位,用 getcontext().prec
来调整精度。
decimal.getcontext().prec = 4
c = Decimal(1) / Decimal(3)
print(c)
# 0.3333
【例子】bool 作用在容器类型变量:X
只要不是空的变量,bool(X)
就是 True
,其余就是 False
。
print(type(''), bool(''), bool('python'))
# False True
print(type(()), bool(()), bool((10,)))
# False True
print(type([]), bool([]), bool([1, 2]))
# False True
print(type({
}), bool({
}), bool({
'a': 1, 'b': 2}))
# False True
print(type(set()), bool(set()), bool({
1, 2}))
# False True
type(object)
print(isinstance(1, int)) # True
print(isinstance(5.2, float)) # True
print(isinstance(True, bool)) # True
print(isinstance('5.2', str)) # True
注:
type()
不会认为子类是一种父类类型,不考虑继承关系。isinstance()
会认为子类是一种父类类型,考虑继承关系。如果要判断两个类型是否相同推荐使用 isinstance()
。
转换为整型 int(x, base=10)
转换为字符串 str(object='')
转换为浮点型 float(x)
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
str()
方式进行转换为字符串输出;sep
是实现分隔符,比如多个参数输出时想要输出中间的分隔字符;end
是输出结束时的字符,默认是换行符\n
;sys.stdout
,也可以重定义为别的文件;flush
是立即把内容输出到流文件,不作缓存。【例子】每次输出结束都用end
设置的参数&
结尾,并没有默认换行。
shoplist = ['apple', 'mango', 'carrot', 'banana']
print("This is printed with 'end='&''.")
for item in shoplist:
print(item, end='&')
print('hello world')
# This is printed with 'end='&''.
# apple&mango&carrot&banana&hello world
【例子】item
值与'another string'
两个值之间用sep
设置的参数&
分割。由于end
参数没有设置,因此默认是输出解释后换行,即end
参数的默认值为\n
。
shoplist = ['apple', 'mango', 'carrot', 'banana']
print("This is printed with 'sep='&''.")
for item in shoplist:
print(item, 'another string', sep='&')
# This is printed with 'sep='&''.
# apple&another string
# mango&another string
# carrot&another string
# banana&another string
二进制有三种不同的表示形式:原码、反码和补码,计算机内部使用补码来表示。
原码:就是其二进制表示(注意,有一位符号位)。
00 00 00 11 -> 3
10 00 00 11 -> -3
反码:正数的反码就是原码,负数的反码是符号位不变,其余位取反(对应正数按位取反)。
00 00 00 11 -> 3
11 11 11 00 -> -3
补码:正数的补码就是原码,负数的补码是反码+1。
00 00 00 11 -> 3
11 11 11 01 -> -3
符号位:最高位为符号位,0表示正数,1表示负数。在位运算中符号位也参与运算。
~
~ 1 = 0
~ 0 = 1
~
把num
的补码中的 0
和 1
全部取反(0 变为 1,1 变为 0)有符号整数的符号位在 ~
运算中同样会取反。
00 00 01 01 -> 5
~
---
11 11 10 10 -> -6
11 11 10 11 -> -5
~
---
00 00 01 00 -> 4
&
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
只有两个对应位都为 1
时才为 1
00 00 01 01 -> 5
&
00 00 01 10 -> 6
---
00 00 01 00 -> 4
|
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0
只要两个对应位中有一个1
时就为1
00 00 01 01 -> 5
|
00 00 01 10 -> 6
---
00 00 01 11 -> 7
^
A ^ B
相当于 A != B
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0
只有两个对应位不同时才为 1
00 00 01 01 -> 5
^
00 00 01 10 -> 6
---
00 00 00 11 -> 3
异或操作的性质:满足交换律和结合律
A: 00 00 11 00
B: 00 00 01 11
A^B: 00 00 10 11
B^A: 00 00 10 11
A^A: 00 00 00 00
A^0: 00 00 11 00
A^B^A: = A^A^B = B = 00 00 01 11
<<
num << i
将num
的二进制表示向左移动i
位所得的值。
00 00 10 11 -> 11
11 << 3
---
01 01 10 00 -> 88
>>
num >> i
将num
的二进制表示向右移动i
位所得的值。
00 00 10 11 -> 11
11 >> 2
---
00 00 00 10 -> 2
<<
,>>
快速计算2
的倍数问题。n << 1 -> 计算 n*2
n >> 1 -> 计算 n/2,负奇数的运算不可用
n << m -> 计算 n*(2^m),即乘以 2 的 m 次方
n >> m -> 计算 n/(2^m),即除以 2 的 m 次方
1 << n -> 2^n
^
快速交换两个整数。a ^= b
b ^= a
a ^= b
#include
using namespace std;
int main()
{
int a = 3, b = 4;
a = a ^ b;
b = b ^ a;
a = a ^ b;
cout << a << " " << b << endl;
}
// output: 4, 3
let a = 3, b = 4
a = 011
(^) b = 100
----------------
a = 111
(^) b = 100
----------------
b = 011
(^) a = 111
----------------
a = 100
a ^ b = b ^ a
a ^ 0 = a
a ^ a = 0
a1 = a0 ^ b0
b1 = b0 ^ a1 = b0 ^ (a0 ^ b0) = b0 ^ a0 ^ b0 = a0 ^ b0 ^ b0 = a0 ^ 0 = a0
a2 = a1 ^ b1 = (a0 ^ b0) ^ a0 = a0 ^ b0 ^ a0 = b0 ^ a0 ^ a0 = b0 ^ 0 = b0
a & (-a)
快速获取a
的最后为 1
位置的整数。(看不太懂)00 00 01 01 -> 5
&
11 11 10 11 -> -5
---
00 00 00 01 -> 1
00 00 11 10 -> 14
&
11 11 00 10 -> -14
---
00 00 00 10 -> 2
一个数的二进制表示可以看作是一个集合(0
表示不在集合中,1
表示在集合中)。
比如集合 {1, 3, 4, 8}
,可以表示成 01 00 01 10 10
而对应的位运算也就可以看作是对集合进行的操作。
元素与集合的操作:
a | (1<<i) -> 把 i 插入到集合中
a & ~(1<<i) -> 把 i 从集合中删除
a & (1<<i) -> 判断 i 是否属于该集合(零不属于,非零属于)
集合之间的操作:
a 补 -> ~a
a 交 b -> a & b
a 并 b -> a | b
a 差 b -> a & (~b)
注意:整数在内存中是以补码的形式存在的,输出自然也是按照补码输出。
assert
这个关键词我们称之为“断言”,当这个关键词后边的条件为 False
时,程序自动崩溃并抛出AssertionError
的异常。
my_list = ['lsgogroup']
my_list.pop(0)
assert len(my_list) > 0
# AssertionError
【例子】在进行单元测试时,可以用来在程序中置入检查点,只有条件为 True 才能让程序正常工作。
assert 3 > 7
# AssertionError
while 布尔表达式:
代码块
else:
代码块
当while
循环正常执行完的情况下,执行else
输出,如果while
循环中执行了跳出循环的语句,比如 break
,将不执行else
代码块的内容。
count = 0
while count < 5:
print("%d is less than 5" % count)
count = count + 1
else:
print("%d is not less than 5" % count)
# 0 is less than 5
# 1 is less than 5
# 2 is less than 5
# 3 is less than 5
# 4 is less than 5
# 5 is not less than 5
dic = {
'a': 1, 'b': 2, 'c': 3, 'd': 4}
for key, value in dic.items():
print(key, value, sep=':', end=' ')
# a:1 b:2 c:3 d:4
dic = {
'a': 1, 'b': 2, 'c': 3, 'd': 4}
for key in dic.keys():
print(key, end=' ')
# a b c d
for 迭代变量 in 可迭代对象:
代码块
else:
代码块
当for
循环正常执行完的情况下,执行else
输出,如果for
循环中执行了跳出循环的语句,比如 break
,将不执行else
代码块的内容,与while - else
语句一样。
for num in range(10, 20): # 迭代 10 到 20 之间的数字
for i in range(2, num): # 根据因子迭代
if num % i == 0: # 确定第一个因子
j = num / i # 计算第二个因子
print('%d 等于 %d * %d' % (num, i, j))
break # 跳出当前循环
else: # 循环的 else 部分
print(num, '是一个质数')
# 10 等于 2 * 5
# 11 是一个质数
# 12 等于 2 * 6
# 13 是一个质数
# 14 等于 2 * 7
# 15 等于 3 * 5
# 16 等于 2 * 8
# 17 是一个质数
# 18 等于 2 * 9
# 19 是一个质数
enumerate(sequence, [start=0])
sequence:一个序列、迭代器或其他支持迭代对象。
start:下标起始位置。
返回 enumerate(枚举) 对象
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
lst = list(enumerate(seasons))
print(lst)
# [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
lst = list(enumerate(seasons, start=1)) # 下标从 1 开始
print(lst)
# [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
break
语句可以跳出当前所在层的循环。
continue
终止本轮循环并开始下一轮循环。
for i in range(10):
if i % 2 != 0:
print(i)
continue
i += 2
print(i)
# 2
# 1
# 4
# 3
# 6
# 5
# 8
# 7
# 10
# 9
x = [-4, -2, 0, 2, 4]
y = [a * 2 for a in x]
print(y)
# [-8, -4, 0, 4, 8]
x = [i ** 2 for i in range(1, 10)]
print(x)
# [1, 4, 9, 16, 25, 36, 49, 64, 81]
x = [(i, i ** 2) for i in range(6)]
print(x)
# [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
x = [i for i in range(100) if (i % 2) != 0 and (i % 3) == 0]
print(x)
# [3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93, 99]
a = [(i, j) for i in range(0, 3) for j in range(0, 3)]
print(a)
# [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
x = [[i, j] for i in range(0, 3) for j in range(0, 3)]
print(x)
# [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
x[0][0] = 10
print(x)
# [[10, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]]
a = [(i, j) for i in range(0, 3) if i < 1 for j in range(0, 3) if j > 1]
print(a)
# [(0, 2)]
a = (x for x in range(10))
print(a)
# at 0x0000025BE511CC48>
print(tuple(a))
# (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
b = {
i: i % 2 == 0 for i in range(10) if i % 3 == 0}
print(b)
# {0: True, 3: False, 6: True, 9: False}
c = {
i for i in [1, 2, 3, 4, 5, 5, 6, 4, 3, 2, 1]}
print(c)
# {1, 2, 3, 4, 5, 6}
e = (i for i in range(10))
print(e)
# at 0x0000007A0B8D01B0>
print(next(e)) # 0
print(next(e)) # 1
for each in e:
print(each, end=' ')
# 2 3 4 5 6 7 8 9
s = sum([i for i in range(101)])
print(s) # 5050
s = sum((i for i in range(101)))
print(s) # 5050
BaseException
:所有异常的 基类Exception
:常规异常的 基类StandardError
:所有的内建标准异常的基类ArithmeticError
:所有数值计算异常的基类FloatingPointError
:浮点计算异常OverflowError
:数值运算超出最大限制ZeroDivisionError
:除数为零AssertionError
:断言语句(assert)失败AttributeError
:尝试访问未知的对象属性EOFError
:没有内建输入,到达EOF标记EnvironmentError
:操作系统异常的基类IOError
:输入/输出操作失败OSError
:操作系统产生的异常(例如打开一个不存在的文件)WindowsError
:系统调用失败ImportError
:导入模块失败的时候KeyboardInterrupt
:用户中断执行LookupError
:无效数据查询的基类IndexError
:索引超出序列的范围KeyError
:字典中查找一个不存在的关键字MemoryError
:内存溢出(可通过删除对象释放内存)NameError
:尝试访问一个不存在的变量UnboundLocalError
:访问未初始化的本地变量ReferenceError
:弱引用试图访问已经垃圾回收了的对象RuntimeError
:一般的运行时异常NotImplementedError
:尚未实现的方法SyntaxError
:语法错误导致的异常IndentationError
:缩进错误导致的异常TabError
:Tab和空格混用SystemError
:一般的解释器系统异常TypeError
:不同类型间的无效操作ValueError
:传入无效的参数UnicodeError
:Unicode相关的异常UnicodeDecodeError
:Unicode解码时的异常UnicodeEncodeError
:Unicode编码错误导致的异常UnicodeTranslateError
:Unicode转换错误导致的异常Warning
:警告的基类DeprecationWarning
:关于被弃用的特征的警告FutureWarning
:关于构造将来语义会有改变的警告UserWarning
:用户代码生成的警告PendingDeprecationWarning
:关于特性将会被废弃的警告RuntimeWarning
:可疑的运行时行为(runtime behavior)的警告SyntaxWarning
:可疑语法的警告ImportWarning
:用于在导入模块过程中触发的警告UnicodeWarning
:与Unicode相关的警告BytesWarning
:与字节或字节码相关的警告ResourceWarning
:与资源使用相关的警告try:
检测范围
except Exception[as reason]:
出现异常后的处理代码
【例子】
try:
f = open('test.txt')
print(f.read())
f.close()
except OSError:
print('打开文件出错')
# 打开文件出错
【例子】
try:
f = open('test.txt')
print(f.read())
f.close()
except OSError as error:
print('打开文件出错\n原因是:' + str(error))
# 打开文件出错
# 原因是:[Errno 2] No such file or directory: 'test.txt'
一个try
语句可能包含多个except
子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。
【例子】
try:
int("abc")
s = 1 + '1'
f = open('test.txt')
print(f.read())
f.close()
except OSError as error:
print('打开文件出错\n原因是:' + str(error))
except TypeError as error:
print('类型出错\n原因是:' + str(error))
except ValueError as error:
print('数值出错\n原因是:' + str(error))
# 数值出错
# 原因是:invalid literal for int() with base 10: 'abc'
【例子】
dict1 = {
'a': 1, 'b': 2, 'v': 22}
try:
x = dict1['y']
except LookupError:
print('查询错误')
except KeyError:
print('键错误')
else:
print(x)
# 查询错误
try-except-else
语句尝试查询不在dict
中的键值对,从而引发了异常。这一异常准确地说应属于KeyError
,但由于KeyError
是LookupError
的子类,且将LookupError
置于KeyError
之前,因此程序优先执行该except
代码块。所以,使用多个except
代码块时,必须坚持对其规范排序,要从最具针对性的异常到最通用的异常。
【例子】
dict1 = {
'a': 1, 'b': 2, 'v': 22}
try:
x = dict1['y']
except KeyError:
print('键错误')
except LookupError:
print('查询错误')
else:
print(x)
# 键错误
【例子】一个 except
子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组。
try:
s = 1 + '1'
int("abc")
f = open('test.txt')
print(f.read())
f.close()
except (OSError, TypeError, ValueError) as error:
print('出错了!\n原因是:' + str(error))
# 出错了!
# 原因是:unsupported operand type(s) for +: 'int' and 'str'
try
: 检测范围
except Exception[as reason]
:出现异常后的处理代码
finally
: 无论如何都会被执行的代码
不管try
子句里面有没有发生异常,finally
子句都会执行。
【例子】如果一个异常在try
子句里被抛出,而又没有任何的except
把它截住,那么这个异常会在finally
子句执行后被抛出。
def divide(x, y):
try:
result = x / y
print("result is", result)
except ZeroDivisionError:
print("division by zero!")
finally:
print("executing finally clause")
divide(2, 1)
# result is 2.0
# executing finally clause
divide(2, 0)
# division by zero!
# executing finally clause
divide("2", "1")
# executing finally clause
# TypeError: unsupported operand type(s) for /: 'str' and 'str'
如果在 try
子句执行时没有发生异常,Python将执行 else
语句后的语句。
try:
检测范围
except:
出现异常后的处理代码
else:
如果没有异常执行这块代码
使用except
而不带任何异常类型,这不是一个很好的方式,我们不能通过该程序识别出具体的异常信息,因为它捕获所有的异常。
try
: 检测范围
except(Exception1[, Exception2[,...ExceptionN]]])
: 发生以上多个异常中的一个,执行这块代码
else
: 如果没有异常执行这块代码
【例子】
try:
fh = open("testfile.txt", "w")
fh.write("这是一个测试文件,用于测试异常!!")
except IOError:
print("Error: 没有找到文件或读取文件失败")
else:
print("内容写入文件成功")
fh.close()
# 内容写入文件成功
注意:else
语句的存在必须以except
语句的存在为前提,在没有except
语句的try
语句中使用else
语句,会引发语法错误。
Python 使用raise
语句抛出一个指定的异常。
try:
raise NameError('HiThere')
except NameError:
print('An exception flew by!')
# An exception flew by!