Fork me on GitHub

Python高级编程

开始Python高级编程学习!

img

== | is

== : 用来判断两个值是否相等

is : 判断两个遍变量的内容是否为同一个东西

1
2
3
4
5
6
7
8
9
a = [1,2,3]
b = [1,2,3]
a == b
# True
a is b
# False
c = b
b is c
# True

当然,如果变量值为数字,则a is b成立的范围为由一个负数到100多左右,当变量的值超过这个范围,则不成立。


深拷贝 | 浅拷贝

浅拷贝

浅拷贝:没有将值直接赋予给另一个变量,而是把变量指向的地址赋给另一个变量,故两个变量的地址都是相同的。

1
2
3
a = [1,2,3]
b = a
# id(a) == id(b)

深拷贝

深拷贝:将值赋予给另一个变量,且两者的id地址不同

1
2
3
4
import copy
a = [1,2,3]
b = copy.deepcopy(a)
# id(a) != id(b)
1
2
3
4
5
6
import copy
a = [1,2,3]
b = [4,5,6]
c = [a,b]
d = copy.deeycopy(c)
# 此时为深拷贝,改变a,b时不会改变d的内容

其他拷贝

另一种拷贝方式:copy.copy()

1
2
3
4
5
import copy
a = [1,2,3]
b = [4,5,6]
c = copy.copy([a,b])
# 此时a,b改变也会使得c改变,但a,b的地址不一样

此时有另一个问题出来,如果当copy.copy()拷贝的是一个元组,由于元组为不可变对象,则此时ab的地址为一样。

总结:copy.copy()根据拷贝的是可变类型还是不可变类型,拷贝的内容是不一样的。

进制–位运算

真值

1
2
3
4
+1 = 0000 0000 0000 0001
-1 = 1000 0000 0000 0001

+1 + (-1) = 1000 0000 0000 0010 ==> -2
  • 正数: 原码 = 补码 = 反码
  • 负数: 反码 = 原码–符号位不变,其他位取反 ; 补码 = 反码 + 1
计算-1 + 1应该使用补码相加,即运算的时候都是按照补码计算的

进制转换

  • 二进制:bin(18) ==> 0b10010
1
2
3
a = 0b10010
a
>>> 18
  • 八进制:oct(18) ==> 0o22
  • 十六进制:hex(18) ==> 0x12
以0开头的进制都是以其他进制转换为十进制。
  • 其他进制转换为十进制:int("0xxx", 2/8/16)

位运算

可以使用位运算进行快速的进行元素的乘除–二进制左右移动

1.偶数倍乘除 >> <<

案例:

1
2
3
4
5
6
7
# 5的两倍 (5左移动1位)
5<<1
# 10

# 8 处以 4
8>>2
# 2

箭头指哪,就往哪移动

2.按位异或

两个数的二进制,不同的数字都设置为1,相同的二进制位则为0

1
2
3
num = 0111
num = num^0101
>>> 0010

3.取反

一个数原来的二进制位数为1的变为0,原来为0的变为1

1
2
3
num = 9
num = ~num
>>> -10

私有化

1
2
3
4
5
6
7
class Test:
def __init__(self):
self.__num = 10
def getnum(self, num):
self.__num = num
a = Test()
print(a.getnum(15))

迭代器

可以使用for循环,从一个位置开始,然后后面的接在上一次循环的位置继续循环 – 迭代

判断对象是否可以迭代

使用isinstance()判断一个对象是否为iterable对象
1
2
3
4
5
from collections import Iterable
isinstance([], Iterable)
# True
isinstance({}, Iterable)
# True

将生成器转换为迭代器

使用iter()函数,配合next()使用
1
2
3
4
5
a = [1,2,3]

b = iter(a)
next(b)
next(b)

闭包

闭包
: 函数体内,定义另一个函数,并且返回这个函数

1
2
3
4
5
6
7
8
def test(num):
def test1(num1):
print(num1+num)
return test1

r = test(100)
r(1) # 第二次传值给test1()
# number = 100 + 1

装饰器

property

1.私有方法添加getter/setter方法

2.使用property升级getter/setter功能

例如在设置了私有方法,调用变量时,直接自动调用类中的方法

1
2
3
4
5
6
7
8
9
10
11
12
class Money:
def __init__(self):
self.__money = 0

def getMoney(self):
return self.__money
def setMoney(self,value):
if isinstance(value, int) # 判断value是否为整数
self.__money = value

# 为getMoney和setMoney方法添加property属性
Money = property(getMoney, setMoney)

解释:

  • init方法中设定了私有属性
  • setMoney/getMoney方法用来修改私有属性

Money = property(getMoney, setMoney)

  • 对象.Money = xxx:可以直接使用setMoney方法,将xxx传给setMoney,即相当于对象.setMoney(9)

改进:使用装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Test:
def __init__(self):
self.__num = 100

@property
def num(self):
return self.__num
@num.setter
def num(self, newNum):
self.__num = newNum
# 上述步骤等价于设置了 num = property(getNum, setNum)
t = Test()
t.num = 100 # 等价于 t.setNum(100)
print(t.num) # 等价于 t.getNum()

创建装饰器

看个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def w1(func):
def inner():
print('--验证--')
func()
return inner # 闭包
# f1 = w1(f1) ,与下列装饰器操作等效
@w1
def f1():
print('--f1--')

f1()
# 输出
# --验证--
# --f1--

其中@w1作用就等效于f1=w1(f1)

当然也可以对一个函数添加多个装饰器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def w1(func):
def inner():
print('--验证1--')
func()
return inner # 闭包

def w2(func):
def inner():
print('--验证2--')
func()
return inner # 闭包
@w1
@w2
def f1():
print('--f1--')

f1()
# 输出
# --验证1--
# --验证2--
# --f1--

顺序为由内层至外层,即由w1 - w2。等价为 f1 = w1(w2(f1))。

终极解释:调用装饰器为从上到下,而装饰函数是从下到上。

装饰器执行的时间

1
2
3
4
5
def w1(func):
# code here
@w1
def f1():
print('--f1--')

在上述代码中,执行至@w1时,就开始调用w1函数了,即把f1 = w1(f1)直接简写为@w1.

带参数的装饰器

1
2
3
4
5
6
7
8
9
10
11
12
def w1(func):
# 记得为闭包添加参数哦~
def inner(*args, **kwarg):
print('--验证1--')
# 这里也要传入参数呢~
func(*args, **kwarg)
return inner # 闭包
@w1
def f1(a,b):
print('--f1-a-b-'%(a,b))

f1(11,22)
由于f1函数有两个参数,则在装饰器内的闭包要调用f1函数时,要为func传入参数。

在闭包内,如果被装饰的函数有多个参数,可以为闭包函数参数列表使用不定长参数*args,**kwarg。

含有返回值的装饰器

1
2
3
4
5
6
7
8
9
10
11
12
13
def w1(func):
# 记得为闭包添加参数哦~
def inner(*args, **kwarg):
print('--验证1--')
# 这里也要传入参数呢~
result = func(*args, **kwarg)
return result
return inner # 闭包
@w1
def f1(a,b):
return (a+b)

f1(11,22)
被装饰函数具有返回值,如果装饰器闭包函数要返回函数的返回值,则需要命名一个变量,来存储被装饰函数返回值。
喜欢的可以对我小额打赏哦,鼓励小编推出更多优质内容~

本文标题:Python高级编程

文章作者:Keithx的博客~

发布时间:2018年10月19日 - 16:10

最后更新:2018年11月05日 - 19:11

原始链接:http://edmath.cn/Python-Python-Advanced-2018-10-19-Python高级编程.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

0%
;