2021年10月

迭代

我们用for循环把元素从容器里面取出来的过程叫做迭代

迭代是访问集合的一种方式,迭代器是一个可以记住遍历的位置的对象,迭代器对象从集合的第一个元素开始访问,知道所有元素被访问完结束,迭代器只能前进不能后退

list\tuple\str\dict\set等元素类型可以使用for...in...来取出里面的元素,这些称为可迭代对象。所有能够通过迭代来取出元素的都是可迭代对象

可以使用isinstance来判断是否可迭代

from collections import  Iterable
l = [1,2,3,4]

print(isinstance(l,Iterable))

可迭代对象内部都有__iter__方法

l = [1,2,3,4]

print(dir(l))

迭代器必须有iter和next方法

l = [1,2,3,4]
l_iter = l.__iter__()
print(dir(l_iter))
item = l_iter.__next__()
print(item)#输出1

可以用Iterable来判断是否是迭代器

from collections import  Iterator
l = [1,2,3,4]
l_iter = l.__iter__()
print(isinstance(l_iter,Iterator))

迭代是访问集合的一种方式,迭代器是一个可以记住遍历的位置的对象,迭代器对象从集合的第一个元素开始访问,知道所有元素被访问完结束,迭代器只能前进不能后退

list\tuple\str\dict\set等元素类型可以使用for...in...来取出里面的元素,这些称为可迭代对象。所有能够通过迭代来取出元素的都是可迭代对象

可以使用isinstance来判断是否可迭代

from collections import  Iterable
l = [1,2,3,4]

print(isinstance(l,Iterable))

可迭代对象内部都有__iter__方法

l = [1,2,3,4]

print(dir(l))

迭代器必须有iter和next方法

l = [1,2,3,4]
l_iter = l.__iter__()
print(dir(l_iter))
item = l_iter.__next__()
print(item)#输出1

可以用Iterable来判断是否是迭代器

from collections import  Iterator
l = [1,2,3,4]
l_iter = l.__iter__()
print(isinstance(l_iter,Iterator))

生成器

我们有时候想要获取函数的一些处理结果,但是如果用return,那么函数就结束了,如果用print,则可用性会变差,这里我们可以使用yield,生成器

def generator():
    a = 1
    print('给a赋值')
    yield a #k1
    b = 2
    print('给b赋值')
    yield b
g = generator() #生成器,不执行内部代码
print(g,next(g)) #触发运行,跑到k1停住
print(next(g)) #执行到b

# 给a赋值
# <generator object generator at 0x0000023AEB9F4BA0> 1
# 给b赋值
# 2
def generator():
    a = '米饭'
    for i in range(1000000):
        a = yield f'吃了第{i}个{a}陷的包子'#先执行yield返回,然后再执行a的赋值语句


pro = generator()
print(pro.__next__())
print(pro.send('三鲜肉'))#send=赋值+next
print(pro.send('粉丝'))
print(pro.send('咖喱牛肉'))
print(pro.send('雪菜'))
print(pro.send('牛肉'))

# 吃了第0个米饭陷的包子
# 吃了第1个三鲜肉陷的包子
# 吃了第2个粉丝陷的包子
# 吃了第3个咖喱牛肉陷的包子
# 吃了第4个雪菜陷的包子
# 吃了第5个牛肉陷的包子

# Process finished with exit code 0

列表推导式

a = [i for i in range(100)]

print(sum([i for i in range(1,101)]))

num = [i*i for i in range(100) if i % 3 is 0]

name = [['zhangsan','lisi','lixiuli','wangwu'],['tokugawa','ono','yochida','lilisu']]
print([namel for lst in name for namel in lst if 'li' in namel])#先取列表再取元素

name = ['zhangsan','lisi','lixiuli','wangwu','yochida']
print([namel for namel in name if 'li' in namel])

print('\n'.join('\t'.join([f'{i} x {j} = {i * j}' for i in range(1,j+1)])for j in range(1,10)))#99乘法表

把字母转小写并合并值

dic1 = {'a':1,'b':2,'y':1, 'A':4,'Y':9}
dict2 = {k.lower():dic1.get(k.lower(),0)+dic1.get(k.upper(),0) for k in dic1}
print(dict2)

字典推导式

k1 = {'a':1,'b':2,'c':3}
k2 = {k1[k]:k for k in k1}
print(k2)

格式化输出

a = int(input("a = "))
b = float(input("b = "))
print('%d %% %f = %.1f' % (a,b,a/b))

%d 表示整形,%f表示浮点数,%.1f表示保留一位小数,%%表示%,%s表示字符串

3.6以后可以以这种方式进行输出

a, b = 5, 10
print(f'{a} * {b} = {a * b}')

真值判断

a = int(input("a = "))
is_public = a % 6 ==0 and a % 3 ==0
print(is_public)

if

a = input("a = ")
if a =='pass' or a == 'stu':
    print('hello')
else:
    print('no')

循环

for

a = int(input("a = "))
sum = 0
for x in range(a):  #注意此处range是左闭右开
    sum += x
print(sum)

while

import random
a = random.randint(0,10) #此处为闭区间

while True:
    b = int(input("please input a number"))
    if b > a :
        print("大")

    elif b < a:
        print("小")

    elif b == a:
        print("对了!")
        break

函数

def panduan(num):   #判断奇偶
    if type(num) == int:
        if num % 2 ==0:
            print("是偶数")
        elif num % 2 ==1:
            print("是奇数")
    else:
        print("输的啥玩意")


if __name__ == "__main__":
    a = int(input("input a number"))
    panduan(a)

数组例子

def panduan(num):   #判断奇偶,这里可以进行数组
    for x in range(len(num)):
        if type(num[x]) == int:
            if num[x] % 2 ==0:
                print('%d 是偶数'%(num[x]))
            elif num[x] % 2 ==1:
                print("%d 是奇数"%(num[x]))
        else:
            print("输的啥玩意")


if __name__ == "__main__":
    a = input("input a number")
    num = [int(n) for n in a.split()]
    panduan(num)

数量可变参数

def panduan(num):   #判断奇偶
    for x in range(len(num)):
        if type(num[x]) == int:
            if num[x] % 2 ==0:
                print('%d 是偶数'%(num[x]))
            elif num[x] % 2 ==1:
                print("%d 是奇数"%(num[x]))
        else:
            print("输的啥玩意")


if __name__ == "__main__":
    a = input("input a number")
    num = [int(n) for n in a.split()]
    panduan(num)

此处结果为
2
(3, 4, 5)

动态传参,可以传入任意多个参数,作为元组

def max_num(*args):
    max_one = 0
    for i in args:
        if i > max_one:
            max_one = i
    return max_one

两个星号传入的是键值对

def max_num(**args):
    print(args)

max_num(site='osaka',num=1234567)

python 闭包

from urllib.request import urlopen

def func():
    content = urlopen('http://myvip.ipip.net')
    def get_content():
        return content
    return get_content

code = func() #此处code传入的是get_content函数的地址
content = code() #此处等于执行get_content()
print(content.decode('utf-8'))

#这样在content获取了一次地址后,以后只需调用第一次的地址,不用再打开网页重新获取了

修饰器

def decorator(func):
    def wrapper(*args, **kwargs):
        print('123')
        return func(*args, **kwargs)

    return wrapper

def say_hello():
    print('同学你好')

say_hello_super = decorator(say_hello)
say_hello_super()


#等同于

def decorator(func):
    def wrapper(*args, **kwargs):
        print('123')
        return func(*args, **kwargs)

    return wrapper

@decorator
def say_hello(): #say_hell0 = decorator(say_hello)
    print('同学你好')

say_hello()

模块与调用

以上面的panduan(num)这个函数为例,现在我们把他放在test1.py里面,如果我们想要使用这个函数,我们可以import test1

但是,如果出现同名函数,后面的那个会覆盖掉前面的,如上面panduan函数第一个是直接判断数字,第二个是能够处理数组的,如果在main里面同时写这两个函数,主程序调用时效果会是调用数组的那个。此时我们假设把直接判断的放进test1.py,把判断数组的放进test2.py,然后我们想要调用哪个就improt哪个头文件,如from test2 import panduan,或者

import test1 as t1
import test2 as t2

t1.panduan(num1)
t2.panduan(num2)

class Test:
    # __init__是一个特殊方法用于在创建对象时进行初始化操作
    # 如果你想要把属性的权限设为私有,只需要在他们前面加双下划线
    def __init__(self, foo):
        self.__foo = foo

    def __bar(self):
        print(self.__foo)
        print('__bar')

    # 我们也可以在属性前面加单下划线,表示其是受保护的

class Person(object):

    # 限定Person对象只能绑定_name, _age和_gender属性
    __slots__ = ('_name', '_age', '_gender')

    def __init__(self, name, age):
        self._name = name
        self._age = age

    @property
    def name(self):
        return self._name

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, age):
        self._age = age

    #@property是装饰器,可以用来修饰只读属性

    #@property用在方法上,可以把方法变成属性

class DataSet(object):
  @property
  def method_with_property(self): ##含有@property
      return 15
  def method_without_property(self): ##不含@property
      return 15

l = DataSet()
print(l.method_with_property) # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。
print(l.method_without_property())  #没有加@property , 必须使用正常的调用方法的形式,即在后面加()

# 或者@property可与属性结合,隐藏属性名来达到安全的效果

class DataSet(object):
    def __init__(self):
        self._images = 1
        self._labels = 2 #定义属性的名称
    @property
    def images(self): #方法加入@property后,这个方法相当于一个属性,这个属性可以让用户进行使用,而且用户有没办法随意修改。
        return self._images 
    @property
    def labels(self):
        return self._labels
l = DataSet()
#用户进行属性调用的时候,直接调用images即可,而不用知道属性名_images,因此用户无法更改属性,从而保护了类的属性。
print(l.images) # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()。

静态方法

from math import sqrt


class Triangle(object):

    def __init__(self, a, b, c):
        self._a = a
        self._b = b
        self._c = c

    @staticmethod
    def is_valid(a, b, c):
        return a + b > c and b + c > a and a + c > b

def main():
    a, b, c = 3, 4, 5
    # 静态方法和类方法都是通过给类发消息来调用的
    if Triangle.is_valid(a, b, c):
        t = Triangle(a, b, c)
        print(t.perimeter())
        # 也可以通过给类发消息来调用对象方法但是要传入接收消息的对象作为参数
        # print(Triangle.perimeter(t))
        print(t.area())
        # print(Triangle.area(t))
    else:
        print('无法构成三角形.')


if __name__ == '__main__':
    main()

继承

class model(object):
    def __init__(a,b):

.......


class mod2(model):

    def __init__(a,b,c):
        super().__init__(a,b)
        self.c = c

文件读写

操作模式具体含义
'r'读取 (默认)
'w'写入(会先截断之前的内容)
'x'写入,如果文件已经存在会产生异常
'a'追加,将内容写入到已有文件的末尾
'b'二进制模式
't'文本模式(默认)
'+'更新(既可以读又可以写)
f = open('./xx.txt', 'r', encoding='utf-8')
print(f.read())
f.close()


#用try来报错示例
try:
    fh = open("testfile", "w")
    fh.write("这是一个测试文件,用于测试异常!!")
except IOError:
    print "Error: 没有找到文件或读取文件失败"
else:
    print "内容写入文件成功"
    fh.close()


#逐行读取
for line in open("foo.txt"):
    print line, #,会忽略换行符


#快速方法,结束时会自动关闭文件
with open(xxxx) as f:
    print(f.read())

用户管理

/etc/passwd,/etc/shadow,/etc/group

id

显示用户id及所属群组的id

0:root

1-999:系统用户

1000+普通用户

useradd

useradd name
-g为添加的用户指定相应的用户组
-d path 为新添加的用户指定home目录
-u 指定用户id

当创建用户user时出现Creating mailbox file: File exists,直接删除/var/spool/mail/ 和/home/user

usermod

修改用户账号

-d path更改登录的目录,/sbin/nologin会让这个用户不能登录
-u id 修改用户的uid

userdel

删除用户账号
-r删除登入目录

passwd

更改使用者的密码

组管理

用户和组对应的关系在/etc/group

组的配置文件 /etc/login.defs

groupadd

--g 指定组id
--r 创建系统工作组,组id小于500
--k 覆盖配置文件/etc/login.defs

avatar

groupmod

-n 改名
-g 允许使用重复gid
-n 将组id改为gid

avatar

groupdel

删除组

gpassword

管理组成员

-a 添加用户到组
-d 删除用户
[root@localhost ~]# useradd xiaoming
[root@localhost ~]# id xiaoming
uid=8849(xiaoming) gid=8849(xiaoming) groups=8849(xiaoming)
[root@localhost ~]# groupadd -g 114514 xiabeize
[root@localhost ~]# tail -n 1 /etc/group
xiabeize:x:114514:
[root@localhost ~]# gpasswd -a xiaoming xiabeize
Adding user xiaoming to group xiabeize
[root@localhost ~]# tail -n 1 /etc/group
xiabeize:x:114514:xiaoming
[root@localhost ~]# id xiaoming
uid=8849(xiaoming) gid=8849(xiaoming) groups=8849(xiaoming),114514(xiabeize)

练习

[root@localhost ~]# useradd -u 8888 lisi
[root@localhost ~]# groupadd -g 9999 test
[root@localhost ~]# gpasswd -a lisi test
Adding user lisi to group test
[root@localhost ~]# tail -n 1 /etc/group
test:x:9999:lisi
[root@localhost ~]# groupdel test
[root@localhost ~]# tail -n 1 /etc/group
lisi:x:8888:
[root@localhost ~]# id lisi
uid=8888(lisi) gid=8888(lisi) groups=8888(lisi)
[root@localhost ~]# userdel -r lisi
[root@localhost ~]# id lisi
id: lisi: no such user