Python007继承和多态

继承

记得有句经典话,你可以使用你爸的抽屉,但你只有使用权,而没有抽屉所有权,因为抽屉是你爸的

所有类默认继承 object(object是所有类的基类)

1
2
3
4
5
6
7
class Cat:
pass

class Cat(object):
pass

#两种方式一样 默认继承object

单继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Cat:
def run(self):
print('----run---')

class Bosi(Cat):
pass

class Jiafei(Cat):
pass

bosi = Bosi()
bosi.run()

jf = Jiafei()
jf.run()

继承的注意点,后代无法使用父类的私有属性和方法

你的牙刷和你爸的牙刷属于私有的

重写的应用

1
2
3
4
5
6
7
8
9
class Cat:
def run(self):
print('----run---')

class Bosi(Cat):
def run(self):
print('----run RUN RUN---')

# 波斯猫的run方法跟父类不一致的时候可以自行定义行为——重写

如果想要在重写的方法里调用父类的方法

1
2
3
4
5
6
7
8
class Cat:
def run(self):
print('----run---')

class Bosi(Cat):
def run(self):
super().run()
print('----run RUN RUN---')

多继承

  • 马驴骡子实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Ma(object):
def pao(self):
print('----100km/h 跑----')

class Lv(object):
def tuowupin(self):
print('----托物品----')

# 多继承
class Luozi(Ma,Lv):
pass

luozi = Luozi()
luozi.pao()
luozi.tuowupin()

注意点:如果马和驴都有 jiao()骡子继承谁的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Ma(object):
def pao(self):
print('----100km/h 跑----')
def jiao(self):
print('----马在叫----')

class Lv(object):
def tuowupin(self):
print('----托物品----')
def jiao(self):
print('----驴在叫----')
# 多继承
class Luozi(Ma,Lv):
pass

luozi = Luozi()
luozi.jiao() #是谁的?

如果继承多个类,每个类都有同名方法

  • 如果是平行关系,则继承写在第一个继承的类
1
2
3
4
5
# 继承Ma的jiao
class Luozi(Ma,Lv):

# 继承Lv的jiao
class Luozi(Lv,Ma):
  • 如果继承的有多重嵌套关系,而且又特别复杂

它有一个mro算法,不在本次总结范围之内

但是你看有查看调用类的先后顺序

1
2
3
print(Luozi.__mro__)
# 打印出继承类的先后顺序
# 继承时寻找方法会从头往后找,使用最先找到的

多态

地下城与勇士实例,以下是伪代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class 勇士:
def 攻击(self):
print('按X XX XXX')

class 法师(勇士):
def 攻击(self):
print('魔法星弹。。。。')

class 鬼剑士(勇士):
def 攻击(self):
print('拔刀斩。。。。')


# 这是一个函数
def fight(obj):
obj.攻击()


fight(勇士()) # '按X XX XXX'
fight(法师()) # '魔法星弹。。。。'
fight(鬼剑士()) # '拔刀斩。。。。'
  • 同样的方法表现方式不一样

不是勇士的子类可不可以调用fight?

可以,但是你要保证你自身有 「攻击( )」

1
2
3
4
5
class 喷火龙:
def 攻击(self):
print("喷出火焰。。。。")

fight(喷火龙())

Python006面向对象之我不是异教徒

稍微懂点js,而且js里的继承是模拟的即使出了ES6 class特性但是它的实质依然是原型链具体请参考之前写的总结文章「继承」

面向对象

什么是面向对象,最深刻的理解莫过于think in java里的灯泡图

虽然今天是python

  • 面向过程
  1. 老张开车去东北
  2. 先搞辆车
  3. 充满油
  4. 踩上油门
  5. 打开百度地图
  6. 东北之旅
  • 面向对象
  1. 打开支付宝飞猪订票 or 火车12306
  2. 我去!!!竟然莫名其妙的就来到了东北

类与对象

  • 类 —> 同类事物的抽象描述
  • 对象 —> 具体的事物
1
2
3
4
5
类    对象

狗 张三家的萨摩

车 邻居家的小汽车

类的构成

  • 类名 狗 Dog
  • 属性 品种、毛色、性别、名字
  • 方法 叫、跑、咬人

定义一个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Class Cat:
#属性

#方法
'''
只要是方法要加入 self参数
不管有没有参数 self为第一个参数
def原来是顶格写 在类里要 缩进一下
'''
def eat(self):
print('吃鱼啦!!!')


# 创建一只猫
a = Cat()
a.eat()

给猫添加属性

1
2
3
4
5
6
a.color = '花色'
# 获取a对象的数据
xxx = a.color # '花色'

# 注意如果没有的属性你还去获取会产生异常
print(a.high) # 报错

如果想在方法里访问 color属性就要这样定义,否则抛出异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Class Cat:
#方法
def xxx(self):
print(self.color)

b = Cat()
# 给对象添加color属性
b.color = 'red'
# 通过方法访问color属性
'''
但是这是一个大坑
必须先声明b.color = 'red' 否则还是报错
因为color是你动态添加的属性
'''
b.xxx() # 'red'

init方法(初始化方法)

创建对象后自动调用

1
2
3
4
5
6
7
8
9
10
class Cat:
# 当创建完一个对象后会立即调用
def __init__(self):
print('haha')

def eat(self):
print('吃鱼啦!!!')

a = Cat()
# 'haha'

稍微好点的挂载属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Cat:
# 当创建完一个对象后会立即调用
def __init__(self,newColor,newHigh):
self.color = newColor
self.high = newHigh
print('haha')

def eat(self):
print('吃鱼啦!!!')

a = Cat('red',50)
# 'haha'
print(a.color)
print(a.high)

扩展-创建对象的浪费之处

1
2
3
4
5
6
7
8
a = Cat()
b = Cat()

'''
a对象里有一个 eat方法
b对象里有一个 eat方法
如果是100个对象就是100个 eat方法 很浪费因为方法的内容都是一样的
'''

str方法(神似js的toString实现)

1
2
3
4
5
6
7
class Cat:
def __str__(self):
return 'haha'

# 这样打印对象的时候就会变成 'haha'
a = Cat()
print(a) # 'haha'

私有属性

目的就是保证属性的私有,不让对象的操作者随意操作属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Person:
def __int__(self,name,age):
self.name = name
self.age = age

laowang = Person("老王",30)
# 属性不私有 就会造成随意篡改
laowang.age -= 1



class Person:
def __int__(self,name,age):
self.name = name
self.age = age
def setNewAge(self,newAge):
self.age = newAge

laowang = Person("老王",30)
# 属性应该有set/get 方法
laowang.setNewAge(300)
# 但是通过 laowang.age -= 1 调用依然可以操作

私有属性

  • 所谓私有,就是不能在外部使用
  • 原来没有添加__的属性,默认是公有
  • 不管是属性还是方法在前面加上 __代表私有外面就无法调用
1
2
3
4
5
6
7
8
9
10
11
class Person:
def __int__(self,name,age):
self.name = name
self.__age = age
def setNewAge(self,newAge):
self.__age = newAge

laowang = Person("老王",30)
laowang.setNewAge(300)
#通过 laowang.__age -= 1 调用报错
# print(laowang.__age) 报错

就是任性的想调用私有方法可以吗? 可以,间接的调用

1
2
3
4
5
6
7
8
9
10
11
class Person:
def __int__(self,name,age):
self.name = name
self.__age = age
def setNewAge(self,newAge):
self.__age = newAge
def __test(self):
print('__test')
def test2(self):
self.__test()
print('test2里调用 __test')

虽然无法调用私有方法和属性,但是可以查看私有的东西

1
2
3
4
5
6
7
dir(类名)

打印该类私有的属性和方法
如果是你自己定义的私有方法__test
会被改名为 _Test__test

隐姓埋名。。。

del方法

当创建一个对象时会默认调用init

当删除一个对象时也会默认调用一个方法就是 del

1
2
3
4
5
6
7
8
class Person:
def __int__(self,name,age):
self.name = name
self.__age = age
def __del__(self):
print('------del-------')

a = Person("xxx",30)
  • python程序结束会调用del
  • 手动删除对象del a 也可以触发del方法调用

如果手动多次del a 程序会挂掉

思考一个问题

1
2
3
4
5
6
7
8
9
10
11
12
a = Person("xxx",30)
# 把a的地址给了 b
b = a

# a和b都指向同一块内存区域(堆) 引用计数为2

del a
#删除了a的引用 并不调用del方法() 引用计数为1
print(b) #正常

del b
#删除了b的引用 并调用del方法 引用计数为0

Python005文件操作

文件操作

  1. 打开文件 open
1
2
3
4
5
6
7
8
9
f = open('text.txt','w')

# 第二个参数代表模式
- r 读
- w 写 存在则覆盖写入,不存在则创建写入
- a 追加内容,存在则追加,不存在创建写入
不常用的。。。。自行科普
- rb 二进制打开
。。。
  1. 关闭文件 close

与open成对出现

1
2
3
f = open('text.txt','w')

f.close()
  1. 文件读写
  • read
1
2
f = open('test.txt')
f.read() # 将文件一次性读完慎用,如果文件5G你内存2G就炸了,真的会爆炸
1
2
3
4
5
6
7
如果文件内容是
1111122222333334444455555

# 读5个字节 再次调用会挨着上次的结果继续读
f.read(5) # 11111
f.read(5) # 22222
f.read(5) # 33333
  • write
1
2
3
f = open('abc.txt','w')
f.write('hahahah')
f.close()
  • readlines
1
2
3
4
5
6
7
8
9
10
11
12
13
f = open('1.txt','r')
f.readlines()

'''
文件有多大也都读取出来,生成一个列表 文件每行占据列表一个元素
[
'fsdafsdfasdafs\n',
'fsdafsdfasdafs\n',
'fsdafsdfasdafs\n',
'fsdafsdfasdafs\n'
'\n'
]
'''
  • readline
1
跟read(5) 类似 它是每次读一行

稳妥的用法是使用read(1000) 每次读取指定的内容

复制一个test.txt 的文件 test[副本].txt

1
2
3
4
5
6
7
8
9
# 打开文件
file_read = open('test.txt','r')
file_write = open('test[副本].txt','w')
# 读取写入内容
content = file_read.read()
file_write.write(content)
# 关闭文件
file_read.close()
file_write.close()

读写文件的最佳实践

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#第一种过于粗暴
#content = file_read.read()
#file_write.write(content)

#第二种依然粗暴
#for content in file_read.readlines():
# file_write.write(content)

#第三种
#content = file_read.read()
#file_write.write(content)
while True:
content = file_read.readline()
if len(content)>0:
file_write.write(content)
else:
break

文件定位

比如你看小说看到了一半被叫走了下次铁定不会从头开始看

  • 获取定位 tell
1
2
3
4
5
6
f.read(1) # 1
f.read(1) # 2
f.read(1) # 3
f.read(1) # 4
f.read(1) # 5
f.tell() # 5
  • seek 自行搜索

文件重命名和删除

需要引入模块 os

  • 重命名
1
2
import os
os.rename("1.txt","2.txt") # 将1.txt重命名为2.txt
  • 删除文件
1
2
import os
os.remove("1.txt")
  • 获取当前目录 请参考命令行pwd
1
2
import os
os.getcwd()
  • 改变默认目录
1
2
import os
os.chdir('./aaa') // 切换目录到当前目录的aaa路径下
  • 获取目录列表
1
2
import os
os.listdir()
  • 删除文件夹
1
2
import os
os.rmdir('./张三')

Python004函数

函数

  • 声明关键字 def
1
2
3
4
5
6
7
8
9
10
11
# 函数声明
def aa():
print("1")
print("2")
print("3")
print("4")
print("5")

# 函数调用

aa()

带参数的函数

1
2
3
4
5
6
7
8
def sum(m,n):
print(m+n)

sum(1,2)
# 3


# sum(1,2,3) 报错 参数要几个传几个

注意事项

  • def顶格写
  • 函数内要有缩进

函数返回值

1
2
def sum(a,b):
return a+b

return的作用

  • 把结果返回给调用者
  • 结束一个函数
  • 如果写了多个return程序不会出现语法错误,并把第一个return的值返回

注意点函数声明要放在最前

它不像js一样函数声明后会提升

  • python里函数声明要前置
  • 先定义后使用

局部变量和全局变量

  • 在函数里定义的变量叫局部变量,离开函数就没了
  • 形参也是局部变量
1
2
3
4
5
6
7
8
9
def test():
a = 1
print(a)

# 1
test()

# 报错
print(a)
  • 全局变量就是定义在函数外
1
2
3
4
5
6
7
8
9
10
num = 100

def test():
#运行正常
print(num)
#报错 全局变量在函数里不能改,会报错
num+=2

test()
# 报错

如何解决全局变量修改报错的问题

  • 在函数内部加上一个 global 声明
1
2
3
4
5
6
7
8
9
num = 100

def test():
global num
print(num)
num+=2

test()
# 102

缺省参数

我的理解就是给参数设置默认值,你传递了就用你的不传递走默认(兜底)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def xxx(a,b,c):
print(a)
print(b)
print(c)

# xxx(1,2) 报错 因为指定要三个参数你传少了

def yyy(a,b,c=33)
print(a)
print(b)
print(c)

yyy(11,22)
# 11
# 22
# 33
  • 缺省参数应该放在最后,避免歧义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 非常歧义的写法 你传递4个参数正确 传递3个我不知道自己试!!!
def xxx(a,b,c=33,d):
print(a)
print(b)
print(c)
print(d)

#多个缺省参数

def yyy(a,b,c,d=44,e=55):
print(a)
print(b)
print(c)
print(d)
print(e)

yyy(11,22,33,1000)
'''
11
22
33
1000
55
'''

# 乱序的传参数(前提你要知道形参叫什么)
def zzz(a,b):
print(a)
print(b)

zzz(b=2,a=1)


# 我就想给e传递参数

yyy(11,22,33,e=2000)
'''
11
22
33
44
2000
'''

不定长参数

1
2
3
4
5
6
7
8
9
10
11
12
13
def xx(a,b,*args,**kwargs):
print(a)
print(b)
print(args)
print(kwargs)

xx(11,22,33,44,55,66,mm=11,nn=22)
'''
11
22
(33,44,55,66)
{mm:11,nn:22}
'''

规定

  • args 写一个「 」表示传递多个没有名字的值的时候放入 args
  • kwargs 写俩个「 」表示传递多余的参数带有名字的值的时候放入 kwargs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
A = [11,22,33]
B = {aa:100,bb:200}

xx(11,22,A,B)
'''
11
22
([11,22,33],{aa:100,bb:200})
{}
'''

xx(11,22,A,pp=B)
'''
11
22
([11,22,33])
{pp:{aa:100,bb:200}}
'''

# 没有名字的参数前加一个 *
xx(11,22,*A,B)
'''
11
22
(11,22,33,{aa:100,bb:200})
{}
'''

# 有名字的参数前加两个 **
xx(11,22,*A,**B)
'''
11
22
(11,22,33)
{aa:100,bb:200}
'''

当列表/元组在做实参传递的时候,如果前面有一个*,表示对其进行解包

1
[11,22,33] =======> 11,22,33

当字典在做实参传递的时候,如果前面有两个*,表示对其进行解包

1
{aa:100,bb:200} =======> aa=100,bb=200

引用

  • 可变数据类型 列表/字典
  • 不可变数据类型 数字/字符串/元组

字段的key可以为。。。

1
2
3
4
5
6
7
8
# 运行正常
M = {a:100,100:100,3.14:314}
M = {(11,22,33):10086}



# 报错
M = {[11,22]:1122}

匿名函数 lambda表达式

1
2
3
4
5
6
7
8
9
10
11
12
def test(a):
return a+1

# 匿名函数 如果是单独使用需要赋值给一个变量
aaa = lambda a:a+1

test(10)
aaa(10)

# 多个参数

bbb = lambda a,b:a+b

注意事项

  • 匿名函数不能写print

把函数当作参数

1
2
3
4
5
def test(a,b,fn):
return fn(a,b)

test(11,22,lambda x,y:x+y)
# 33

排序方法里使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
aa = [
{index:22,age:18},
{index:13,age:22},
{index:33,age:12}
]

# key代表指定的排序列
aa.sort(key = lambda x:x['index'])
'''
[
{index:13,age:22},
{index:22,age:18},
{index:33,age:12}
]

aa.sort(key = lambda x:x['index'],reverse=True)
'''
[
{index:33,age:12},
{index:22,age:18},
{index:13,age:22}
]

'''

Python003列表和元组和字典

列表

1
2
3
names =['aa','bb','cc']
type(names)
# list

遍历列表

1
2
3
4
5
6
7
8
9
infos = ['a','b','c','d']

for temp in infos:
print(temp)

i = 0
while i<len(infos):
print(infos[i])
i+=1

列表操作

  • append(obj) 向列表最后添加一个元素
1
2
3
a = [1,2,3]
a.append(4)
# [1,2,3,4]
  • extend
1
2
3
4
a = [1,2,3,4]
b = [100,200]
a.extend(b)
# [1,2,3,4,100,200]
  • insert(index,obj) 指定位置添加
1
2
3
b = [1,2,3,4]
b.insert(1,99)
# [1,99,2,3,4]

  • in
  • not in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#判断列表里是否存在
# 笨方法
# 笨方法
inputName = 2
flg = 0
names = [1,2,3,4,5]
for name in names:
if name = inputName:
flg = 1
break

# 好方法
if inputName in names:
print('find')
else:
print('not find')
  • index
  • count
1
2
3
4
5
a = [1,1,2,2,3,3,4]
a.index(1,1,3) # 左闭右开[1,3)

a.count(2)
# 2

  • del 根据索引删
  • pop 删最后一个
  • remove 根据值删
1
2
3
4
5
6
a = [1,2,3,4,5,6]
del a[0]
# [2,3,4,5,6]

a.pop()
# [2,3,4,5]

排序

  • sort
  • reverse 逆序
1
2
3
4
5
6
7
8
a = [1,3,4,2]
a.reverse()
# [2,4,3,1]

a.sort()
# [1,2,3,4]
a.sort(reverse=True)
#[4,3,2,1]

元组(tuple)

元组和列表不同之处在于

  • 元组不能修改
  • 元组使用小括号,列表使用方括号
1
a = ('a',1,2,3)

元组的不一致性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
a = (1.0,2.0,3.0)
type(a)
#tuple

b = (1.0)
type(b)
# float
# 元组初始化的时候如果只有一个元素是不会初始化为元组的 会把括号里的值当作实际的类型处理

# 正确做法

c = (1.0,)
type(c)
# tuple

字典

  • 键值对 k/v
  • k不可重复
1
2
3
4
5
6
7
{key:value}

info = {
"name":"悟空",
"age":5000,
"gender":"男"
}

字典操作

1
2
3
4
5
info = {
"name":"悟空",
"age":5000,
"gender":"男"
}
1
2
3
info['name'] 
info.get("name")
# "悟空"
  • 修改

    1
    info["age"] = 10000
  • 删除

1
2
3
4
5
# 删除 info里的 name字段
del info["name"]

# 整个删除
del info
  • 滞空
1
2
3
a = {a:1,b:2}
a.clear()
# {}

字典信息

1
2
3
4
5
6
7
8
9
10
info = {a:1,b:2,c:3}

len(info)
# 3

info.keys()
# ['a','b','c']

info.values()
# [1,2,3]
items

返回包含(k,v)元组的列表

1
2
3
info = {"a":1,"b":2}
info.items()
# [("a",1),("b":2)]
has_key

查看字典中key是否存在

1
2
3
info = {a:1,b:2}
info.has_key('a')
# True
字典的遍历

info = {a:1,b:2,c:3}

  1. 遍历字典的key
1
2
for key in info.keys():
print(key)
  1. 遍历字典的value
1
2
for val in info.values():
print(val)
  1. 遍历字典的
1
2
3
4
5
6
7
8
9
10
for item in info.items():
print(item)

# ("a",1)
# ("b",2)
# ("c",3)

for key,val in info.items():
print(key)
print(val)

扩展问题

如何实现列表带索引的遍历

1
2
3
4
5
6
7
方法1 比较low的方法是声明个变量然后随着循环递增 很low 不写了

方法2
a = ['a','b','c']
for i,v in enumerate(a):
print(i)
print(v)

「+ *」

1
2
3
4
5
6
7
8
9
10
11
12
13
"abc"+"123"
# "abc123"

[11,22,33]+[44,55,66]
# [11,22,33,44,55,66]



"-"*3
# "---"

[11,22,33]*2
# [11,22,33,11,22,33]

内置函数

  • cmp 比较两个值
  • len(item) 计算容器中元素个数
  • max(item) 返回容器中最大的元素
  • min(item) 返回容器中最小的元素
  • del(item) 删除变量
1
2
3
4
5
6
7
8
cmp("hello","itcast")
# -1

cmp("itcast","hello")
# 1

cmp("hello","hello")
# 0

Python002字符串

字符串查找

字符串内查找字符串返回索引

  • find 从左往右,找不到返回 -1
  • rfind 从右往左,找不到返回 -1
  • index 从左往右,找不到报错
  • rindex 从右往左,找不到报错
1
2
3
4
5
str = 'aa bbb cc dd ee'

str.find('aa') 1
str.find('ff') -1
... 懒得写了自己试吧!!!

返回字符串在字符串内出现的次数

1
2
str = 'aa bb cc dd aa'
str.count('aa') #2

字符串替换replace

1
2
str = 'python'
str.replace('py','Py')

split

1
2
3
4
5
6
7
str = 'hello world ha ha'

str.split(" ")
# ['hello','world','ha','ha']

str.split(" ",2)
# ['hello','world','ha ha']

capitalize

把字符串第一个字母变大写

1
2
3
a = 'aa bb cc'
a.capitalize()
Aa bb cc

swapcase

1
2
3
a = 'aa bb cc'
print(a.swapcase()) #大小写翻转
# AA BB CC

title

把字符串每个单词首字母大写

1
2
3
a = 'aa bb cc'
a.title()
Aa Bb Cc

大小写

  • startswith
  • endswith

判断字符串是否以字符串 开头/结尾

1
2
3
4
5
6
7
8
a = 'Hello'

a.startswith('He')
# True

b = 'World'
a.endswith('aa')
# False
  • lower 全部转小写
  • upper 全部转大写

字符串各种处理

  • ljust 指定一个字符长度,返回原字符串左对齐,并用空格填充剩余部分
  • rjust 指定一个字符长度,返回原字符串右对齐,并用空格填充剩余部分
  • center 指定一个字符长度,返回原字符居中对齐,并用空格填充剩余部分
1
2
3
4
5
6
7
8
9
10
11
a = 'hello'
a.ljust(10)
# 'hello '

a = 'hello'
a.rjust(10)
# ' hello'

a = 'hello'
a.center(30)
# ' hello '
  • lstrip 删除字符串左面空白
  • rstrip 删除字符串右面空白
  • strip 删除字符串空白
1
2
3
a = '   hello'
a.lstrip()
# 'hello'
  • partition 把字符分成三部分从左开始
  • rpartition 把字符分成三部分从右开始
1
2
3
a = 'What are you doing'
a.partition('are')
# ['What','are','you doing']
  • splitlines 按照换行符分割
1
2
3
a = 'hello\nworld'
a.splitlines()
# ['hello','world']
  • isalpha 如果字符串所有字符都是字母返回True
  • isdigit 如果字符串所有字符都是数字返回True
  • isalnum 如果字符串所有字符都是字母或数字返回True
  • isspace 如果字符串所有字符都是空格返回True

数组拼接

join

1
2
3
4
str = '_'
a = ['Hi','boy']
str.join(a)
# 'Hi_boy'

format的三种玩法 格式化输出

1
2
3
res='{} {} {}'.format('egon',18,'male')
res='{1} {0} {1}'.format('egon',18,'male')
res='{name} {age} {sex}'.format(sex='male',name='egon',age=18)

strip

1
2
3
4
5
6
7
8
9
10
name='*egon**'
print(name.strip('*'))
print(name.lstrip('*'))
print(name.rstrip('*'))

'''
egon
egon**
*egon
'''

Python001基础

学习仪式 hello world

1
2
3
4
5
6
7
#!/usr/bin/env python
print('hello world')


#!/usr/bin/env python 在linux里代表查找系统环境变量的 python命令路径
但是linux里默认的是2.x版本 而你自己安装的3.x版本python在 usr/local/bin
#!/usr/bin/python

python2 解释器在加载 .py 文件中的代码时,会对内容进行编码(默认ascill)如果有中文就会报错

你应该指定编码

1
2
3
#!/usr/bin/env python
# -*- coding: utf-8 -*-
print("你好,世界")

注释

1
2
3
4
5
6
7
8
9
10
11
12
# 单行注释
# 我是注释
# 我是注释
# 我是注释

'''文档注释'''

'''
dd
dd 多行注释
dd
'''

变量声明

1
2
3
# 与js类似 动态类型具体有那些自行百度

注意布尔值为 True / False

基本类型转换方法

1
2
3
4
a = 1;
str(a) '1'
b = '2'
int(b) 2

格式化输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 格式化输出

# \n换行
# \t tab制表


name = "hjx"
age = 18
height = 199
# print(name+age) 报错 因为 name 和 age类型不一样 相加报错
# print(name+str(age)) 要把age 转换为字符串

print("========================")
print("我叫%s"%name)
print("我叫%s,今年%d岁,身高%dcm"%(name,age,height))
print("========================")
# 检查类型
print(type(name))
print(type(age))
print("========================")
# 输出字符
char1 = 65
char2 = 98

print("%c"%char1)
print("%c"%char2)


#如果我想输出 %
print("%") # 这样会报错的,因为在格式化输出里,你出现%默认为就是占位符的%
print("%%") # 第一个%是对第二个%的转译,告诉Python解释器这只是一个单纯的%,而不是占位符。

print("========================")

# 帮助文档

help(print)

运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
+ 懒得说
- 懒得说
* 懒得说
/ 懒得说
// 取整除 商

11/2 5
11.0/2 5.5

11//2 5
2**2 4
3**3 27
a = 100
b = 111
交换a b的值
a,b = b,a

条件判断if

多重嵌套if使用 tab缩进

1
2
3
if a >10 and a <20 :
if a == 15 :
print("满足条件")

或且非

  • and
  • or
  • not

猜拳游戏

1
2
3
4
5
6
7
8
9
10
import random
com = random.randint(0,2)
user = int(input("猜拳:0剪刀 1石头 2布"))

if (com==0 and user ==1) or (com==1 and user ==2) or (com==2 and user ==0):
print('算你厉害')
elif com == user:
print('平')
else:
print("输了")

in,not in

判断子元素是否在原字符串(字典,列表,集合)中:

1
2
3
#print('喜欢' in 'dkfljadklf喜欢hfjdkas')
#print('a' in 'bcvd')
#print('y' not in 'ofkjdslaf')

while循环

1
2
3
4
5
6
7
8
i = 1
while i<=9:
j = 1
while j<=i:
print("%d*%d=%d"%(j,i,i*j),end="")
j+=1
print("")
i+=1

while else

与其它语言else 一般只与if 搭配不同,在Python 中还有个while …else 语句

while 后面的else 作用是指,当while 循环正常执行完,中间没有被break 中止的话,就会执行else后面的语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
count = 0
while count <= 5 :
count += 1
print("Loop",count)

else:
print("循环正常执行完啦")
print("-----out of while loop ------")

输出如下:

Loop 1
Loop 2
Loop 3
Loop 4
Loop 5
Loop 6
循环正常执行完啦
-----out of while loop ------

如果执行过程中被break啦,就不会执行else的语句啦

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
count = 0
while count <= 5 :
count += 1
if count == 3:break
print("Loop",count)

else:
print("循环正常执行完啦")
print("-----out of while loop ------")

输出如下:

Loop 1
Loop 2
-----out of while loop ------

for 循环

1
2
3
name = 'abcdef'
for temp in name
print(temp)

下标

1
2
3
4
5
6
7
name = 'abcdef'
name[0] 'a'
name[1] 'b'
name[2] 'c'
name[3] 'd'
name[4] 'e'
name[5] 'f'

切片

1
2
3
4
5
6
7
8
9
10
11
name = 'abcdef'

name[0] 'a'

#注意切片来了 ,口诀包头不包尾

name[0:4] 'abcd'
name[1:4] 'bcd'

#超过字符串长度咋办?
name[0:70] 'abcdef'

获取字符长度之len

1
2
3
4
5
#js里  'abc'.length = 3 
#python里
name = 'abcdef'
# 获取字符串长度
len(name) # 6

想要切片返回当前字符串的内容

1
2
3
4
5
6
7
8
9
10
name = 'fasfasdfl;kfdl;askfl;daskl;fkasl;'
length = len(name)
name[0:length]

#简洁写法 都可以获取整个字符串
name[0:]
name[:]
name[::]

# name[]报错

切片之炮打隔一子

1
2
name = 'ababababab'
name[::2] 'aaaaa'
1
name[起始位置:结束位置:步长]

切片之反序

1
2
name = '123456789'
name[::-1] '987654321'

切片其他用法

1
2
3
4
5
6
7
name = 'abcdef'
name[-1] 'f'
name[-2] 'e'

name[0:-1] 'abcde'

name[0:0] ''

Vim001编辑器使用

vim

一种编辑器详情自行百度

它有三种模式

  • 命令模式
  • 编辑模式
  • 末行模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
当你 vi 1.txt后 是命令模式
切换到编辑模式
1. i 当前光标左边插入
2. o 当前光标下一行插入
3. a 当前光标右边插入
4. I 当前光标行首插入
5. A 当前光标行尾插入
切换到命令模式 「esc」


从编辑模式按了「esc」再输入一个冒号 「:」就会进入末行模式
1. wq 保存退出
2. q! 不保存退出
3. x 保存退出
4. q 退出

vim里的智能提示功能

1
2
3
4
5
6
7
8
myname = 'sssss'



此时你又输了一个m
m

你想再次输入 myname不想手敲 「ctrl+n」

进入命令模式

移动光标

  • h 左
  • j 下
  • k 上
  • l 右
  • M 光标移动到行中间行
  • L 定位到屏幕最后一行行首
  • G 移动到指定行,行号 15G 跳到15行
  • gg 跳到第一行
  • yy 复制 8yy 表示从当前光标所在行开始复制 只输入yy代表当前行
  • p 粘贴
  • dd 剪切 8dd 表示从当前光标所在行开始剪切 只输入dd代表当前行
  • u 撤销
  • ctrl + r 反撤销
  • w 向后移动一个字
  • b 向前移动一个字
  • { 按段移动上移
  • } 按段移动下移
  • ctrl + d 翻半屏
  • ctrl + u 翻半屏
  • crrl + f 下翻一屏
  • crrl + b 上翻一屏

命令模式

  • x 删除当前光标后边的字母
  • X 删除当前光标前边的字母
  • D 当前光标删除到行尾
  • d0 当前光标删除到行首
  • dw 删除一个词 光标所在位置

  • << 文本左移

  • 文本右移

Linux003多用户多任务操作

多用户

一个电脑多个用户可以同时登录

多任务

一个电脑可以跑很多程序 QQ 微信 浏览器 QQ音乐

ifconfig

查看网卡信息(一般能看到俩个代表你的虚拟机能上网了)

1
ifconfig | grep '192' 查找一大堆文档中的关键字

vmware虚拟机的网络设置

1
2
3
NAT模式  比如你的window能上网,你想让虚拟机借助它上网(对于交换机来说它只看到一台电脑window)
桥接模式 你想让window上网,而且虚拟机也能上网而不是间接的通过window就用这个(对于交换机它看到了两台电脑)
仅主机模式 在没有网的情况下和windows进行通讯

ping

测试是否能通信

1
ping 192.168.2.123

ssh远程登录

比如阿里云服务器跟这效果一样

1
2
3
4
ssh hjx@192.168.17.76 代表远程登录服务器

如果你第一次登录会让你确认是否连接 ==> yes
然后让你输入密码如果成功了就能远程登录 并且对系统进行远程操作

who命令

查看当前登录的用户信息

1
2
如果你的电脑被攻击了
who可以查看当前谁登录了

whoami当前终端的用户

1
whoami

exit退出登录

1
exit

添加用户账号useradd

1
2
3
4
5
6
7
8
-m 自动创建家目录
-d 路径 指定家目录
useradd aaa -m -d /home/aaa
创建用户 aaa 同时指定家目录为 aaa
通常提示你权限不够

sudo useradd aaa -m -d /home/aaa
会提示你输入这个用户的密码

修改密码passwd

1
2
3
4
5
passwd aaa
可能会提示权限不够

sudo passwd aaa
请输入新密码

su切换用户

1
2
3
4
su aaa 
输入密码
su hjx
输入密码

问题 如果你切换了多个用户然后exit会怎样

1
2
3
4
5
6
su aaa
su bbb
su ccc
su ddd

你当前在 ddd用户 然后输入exit 退出会在 ccc用户
1
2
su aaa 切换后你当前目录在哪还在哪
su - aaa 切换后跳到家目录

userdel删除用户

1
2
userdel abc 删除abc用户但不删除用户的主目录 (一般删除这个)
userdel -r abc 删除abc用户同时删除用户的主目录

sudo添加权限

1
2
3
4
sudo -s 一段时间内不询问你密码(最高权限)

以$结尾代表普通用户
以#结尾代表root用户

用户组的查看

  1. cat etc/group
  2. groupmod + 三次tab键

什么是用户组

1
2
3
4
5
比如你输入 ls -al后显示如下信息
-rw-r--r-- root root
第一个root代表用户
第二个root代表用户组
如果其他用户也在 root用户组那他就有 root用户的权限

添加用户组

1
2
3
4
groupadd YYY
groupdel YYY

权限不够请加sudo

修改用户所在用户组

1
2
3
4
5
6
-g 代表你将来默认的组(主组)
-G 代表向其他组添加用户

usermod -g 用户组 用户名

usermod -g aaa bbb 把bbb用户修改到aaa用户组里

一个用户可以有多个用户组

1
sudo usermod -a -G XXX bbb 将 bbb添加到 XXX组里

chmod修改文件权限

1
2
3
4
5
6
7
8
9
drwxrwxrwx 
第一个rwx代表文件拥有者(用户)的权限
第二个rwx代表同组者里的(用户)的权限
第三个rwx代表其他人的权限

r代表读
w代表写
x代表执行
-代表没有权限

chmod的选项

1
2
3
4
5
6
7
u 代表该文件的所有者user
g 代表用户组的用户group
o 代表其他 other
a 代表所有人 all
+ 增加权限
- 减少权限
= 把当前权限改为现在的权限 =左边是u/g/o/a =右边是 r/w/x

示例

1
2
3
chmod u+x 1.txt 用户增加执行权限
chmod g-w 1.txt 同组者去掉写入权限
chmod u=rwx 1.txt

数字代表权限

1
2
3
4
5
6
7
8
9
10
r读 ==> 对应数字4
w写 ==> 对应数字2
x执行 ==> 对应数字1

chmod 444 1.txt 可读权限
chmod 761 1.txt 用户=可读可写可执行 用户组=可读可写 其他用户=可执行权限


chmod 777 aa 只会修改aa文件夹的权限
chmod 777 aa -R aa目录里的东西全部权限

cal和date查看时间(自行百度)

ps查看进程

1
2
3
4
ps
ps -aux 显示全部信息

PID代表程序运行的进程号

kill终止进程

1
2
kill pid
kill 进程号

关机重启

1
2
3
4
5
reboot 重启
shutdown -r now 重启 但是会给用户提示
shutdown -h now 立刻关机
shutdown -h 20:25 系统在 20:25关机
shutdown -h +10 10分钟后关机

查看磁盘占用 du

1
du -h

用文本编辑器gedit

Linux002难点命令

ln软链接和硬链接

1
2
3
4
5
6
7
8
# 软链接,就是快捷方式  (源文件没了,现在的链接文件都不好使)
# 修改源文件或链接文件操作的都是一个文件
ln -s 源文件 链接文件


# 硬连接,就算删除了源文件不会影响硬链接的查看
# 修改源文件或链接文件操作的都是一个文件
ln 源文件 链接文件

cat 查看文件的内容

1
cat 1.txt

将一个文件的内容填充到一个文件里

1
2
3
4
cat 1.txt > 2.txt

# step1 cat 1.txt 复制 1.txt的内容
# step2 将1.txt的内容复制到 2.txt

复制多个文件

1
cat 1.txt 2.txt > 3.txt 将 1.txt和2.txt的内容复制到 3.txt

grep 文本搜索

从文件中搜索内容

1
2
3
4
5
6
7
8
9
# 如1.txt的内容
abcdefg
Abcdefg
------1----m
------2----n
------3----m
alown
txt
txt
1
2
3
4
5
6
7
8
9
-v显示不包含匹配文本的所有行
-n代表匹配内容的行号
-i 忽略大小写

grep -n 'a' 1.txt 打印所有带a的打印出来

grep -n '^a' 1.txt 打印所有以a开头的打印出来

grep -n 'a$' 1.txt 打印所有以a结尾的打印出来

help

查看帮助文档

1
ls --help

man

是linux提供的手册

1
man ls

历史命令

1
2
3
按上键
或者 history
history将历史命令列举出来

find查找文件

从指定路径查找文件名(条件同样支持正则)

1
2
3
4
5
6
7
8
find ./ -name test.sh 查找当前目录下所有名为 test.sh的文件
find ./ -name .sh 查找当前目录下所有后缀为 .sh的文件
find ./ -name "[A-Z]" 查找当前目录下所有以[A-Z]大写字母开头的文件
find /tmp -size 2M 查找/tmp目录下所有等于2M的文件
find /tmp -size +2M 查找/tmp目录下所有大于2M的文件
find /tmp -size -2M 查找/tmp目录下所有小于2M的文件
find ./ -size +4k -size -5M 查找当前目录下所有大于4k小于5m的文件
find ./ -perm 0777 查找当前目录下权限为777文件或目录

cp 拷贝文件 mv剪切文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cp 源文件  目标文件

选项
-v 显示进度
-r 递归的复制
-i 交互式复制(你确认复制吗?)
-f 强制复制
-a 在复制目录时使用,保留链接/文件属性并递归的复制目录,保留文件原有的属性
(比如失效的软链接文件也会被复制)

递归的赋值目录
cp -r 源文件目录 目标文件目录

cp a b
cp a/* b

mv a b
mv a/* b

压缩和解压缩

tar打包

1
2
3
4
5
-c 生成档案文件,创建打包文件
-v 代表进度
-f 指定档案文件名称f后面一定是.tar文件

tar -cvf test.tar * 把当前路径所有东西打包到 test.tar里

tar打包

1
tar -xvf test.tar 把打包文件还原

gzip 对已经打包的文件进行压缩

1
2
3
4
5
6
7
gzip test.tar 
就会产生 test.tar.gz 文件(打包压缩后的)

gzip test.tar test.tar.gz 跟上面的一样效果(麻烦)


gzip -d test.tar.gz 解压缩 ==> test.tar

简单的方式打包压缩

1
2
3
tar -zcvf test.tar.gz * 把当前目录的东西 打包压缩到 test.tar.gz文件里

tar -zxvf test.tar.gz 把test.tar.gz文件解压缩并且解除打包

bzip2压缩解压

1
2
tar -jcvf aa.tar.bz2 *
tar -jxvf aa.tar.bz2

注意:这几种压缩解压不能混用,即gzip压缩后只能用gzip解压缩

zip 压缩解压

1
2
zip  aa.tar.bz2 *
unzip aa.tar.bz2

which查看命令位置

1
which ls