AI学习_python基础_变量_函数_面向对象_文件操作_高级特性(列表生成式,错误处理)_线程(进程)基础

变量

注意看代码注释!
题外话:Python作为“胶水”语言、兼容性很强,不是因为Python本身很厉害,是因为社区环境很好

变量
值类型
集合类型
数字
整数int
小数float
复数complex
布尔bool
字符串
字典dict
集合set
元组tuple
列表list

字符串操作

使用[]方便的分割字符串:
会切割字符串内[“起始位置” : “结束位置(不包含)”]的字符
输入方式多样,输入负数即会反向切割
输入第三参数会 步进一段距离切割/反向表示切割内容

#字符串索引、切片、自带的函数测试
s = "abcdefghigklmno"

#使用索引获取元素
print("获取元素")
print( s[0] )
#两种使用索引拿到最后一个的元素的方式
print( s[len(s) - 1 ] )
print( s[-1] )

#使用索引进行切片
print("进行切片")
print( s[ : ] )#:左右什么都不写,会将字符串完整保留
print( s[0:1] )#左开右闭进行选择,只拿到第一个元素
print( s[1:5] )


print( s[0:12:2] )
"""切片时加入第二个引号代表:
①为正时,代表进行隔*个字符选择
②为负时,代表反向表示,但不能在已切片的情况下用"""

print("反向切片‘当索引为负时’")
print( s[-5:-1] )#由数字上的从小到大切片,方向依然从左到右

print("字符串的常见用法")
s = "    tom     "

print(len(s))                   #获取长度

print(len(s.strip()))           #去字符串前后的空格
s = s.strip()
print(s.capitalize())           #首字母大写
print(s.find("om"))             #找指定字符位置
print(s.startswith("t"))        #开头是不是这个?
print(s.endswith("m"))          #结尾是不是这个?
print(s.center(11,"*"))         #用填充字符使字符串居中
print(s.isdigit())              #是否只有数字
print(s.isalpha())              #是否只有字符
print(s.upper())                #转全大写!
print(s.lower())                #转全小写……

可改值/不可改值的区别(以字符串/StringIO为例)

可改值类型在效率上,秒杀不可改值
string(自带)、int等数值类型都是“不可改值”
list列表、set集合、dict字典都是“可改值”

#两种类型——可改值和不可改值——字符串的性能对比

#对可改值的字符串类型——StringIO模组的引入
#以及对时间模组——time的引入,注意两种不同的引入方式
from io import StringIO
import time

#开始时间和结束时间的定义,相减即可得到时间性能
start_time = time.time()

#s = "abc"
sio = StringIO("abc")   #对可改值类型字符串的定义
#循环执行1000k万次更改操作
for i in range(10000000):
    #s += "efg"   #49.10713267326355
    sio.write("efg")  #1.8615856170654297
    #对两种字符串类型的“添加”内容操作,注意不止是更改

end_time = time.time()
print( end_time - start_time)#输出的时间对比

原版string需要49秒
可改值StringIO只需1

列表+字典操作:数据库增删改查

注意列表中对键值对操作方式:
for i in students:
然后再i[‘score’]

'''
家庭作业:操作一个简单数据库
1、统计不及格学生的个数
2、打印所有男生的信息
3、计算女生的平均分
4、统计男生的最高分
5、查询手机尾号是2838的同学信息
'''
students = [
{'name':'Tom',   'age': 19, 'score': 92, 'sex': '女', 'tel':'15300022839'},
{'name':'Jerry', 'age': 20, 'score': 40, 'sex': '男', 'tel':'15300022838'},
{'name':'Andy',  'age': 18, 'score': 85, 'sex': '女', 'tel':'15300022837'},
{'name':'Jack',  'age': 16, 'score': 65, 'sex': '男', 'tel':'15300022428'},
{'name':'Rose',  'age': 17, 'score': 59, 'sex': '男', 'tel':'15300022653'},
{'name':'Bob',   'age': 18, 'score': 78, 'sex': '男', 'tel':'15300022867'} ]

not_great = 0               #不及格学生个数
famale_score = 0            #女生的平均分
Number_of_famale = 0        #女生总数
male_max_score = 0          #男生的最高分
tel_2838 = ""               #电话号码为2838的学生信息


print("所有男生信息为:")
for i in students:
    if(i['score'] < 60):
        not_great += 1      #统计不及格人数
    if(i['sex'] == '男'):
        print(i)            #统计男生个数
    if(i['sex'] == '女'):
        famale_score += i['score']      #统计女生总分
        Number_of_famale += 1           #统计女生个数
    if(i['sex'] == '男' and i['score'] >= male_max_score):
        male_max_score = i['score']     #找出男生最高分
    if(i['tel'][-4:] == "2838"):
        tel_2838 = i                    #找到尾号2838的人,并保存他的信息

famale_score = famale_score/Number_of_famale    #计算女生平均分
print("不及格学生个数:", not_great)
print("女生的平均分:", famale_score)
print("男生的最高分:", male_max_score)
print("电话号码为2838的学生信息:", tel_2838)

使用递归实现阶乘(重)、登录系统、lambda 懒人函数生成

注意:在这里展示的一种常见递归使用方式——在函数返回值中递归

#使用递归实现阶乘
def multiply_loop(c):
    if c == 0:
        return 0    #防止输入值为0
    elif c == 1:
        return 1    #当递减为1时,阻止递归继续递减,以防止全为零
    elif c != 0:
        return int(c * multiply_loop(c - 1))    #将输入值 和 比输入值小 1 的值相乘
print(multiply_loop(5))

#用户输入的登录系统,但信息存放到字典中
#以用户名为键、以密码为值、用户名不重复
database = {
    "tom":"123"
}
def login_register():
    #用于控制登录/注册的哨兵变量
    mode = int(input("登录请按1、注册请按2"))

    if mode == 1:
        error_try = 0  # 试错次数

        print("-登录模式-")
        while (error_try < 3):
            user_name = input("请输入用户名")
            password = input("请输入密码")

            # 当 存在此用户名 且 密码不匹配时 :
            if database.get(user_name) and database.get(user_name) != password:
                error_try += 1  #试错标记增加1
                print("密码错误,还可以重试%d次!" % (3 - error_try))
            # 当 不存在此用户名时 :
            elif not database.get(user_name):
                print("此用户名不存在,请重试")
            else:
                print("登录成功")
                break
        if (error_try > 3):
            print("密码错误超过三次!")
    if mode == 2:
        print("-注册模式-")

        while (mode == 2):
            user_name = input("请输入用户名")
            password = input("请输入密码")

            # 当 找得到此用户名时 :
            if database.get(user_name):
                print("此用户名已存在,请重试")
            else:
                database[user_name] = password
                print("成功注册,您注册的信息为:" + user_name + ":" + database[user_name])
                break

    print("当前数据库状态为", end="\t")
    print(database)


#列表在函数中是否可变
list = [1, 2, 3]
def change_list(list):
    list.append("4")#在列表中加入字符串的“4”
change_list(list)

print(list) #答案是:列表可以被函数直接改变

#lambda的使用
x = lambda a,b: a ** b  #用lambda实现幂运算
print(x(2,8))
str_output = lambda a,b: print(str(a) + str(b))  #用lambda实现两段数据转化为字符串,并输出
str_output(90,"人")

#文件读取
import os   #引入文件读取模块

path = "D:\\A_PyCharm\\PycharmProjects\\Day3_Test1"   #指定路径以方便后续访问
file_list = os.listdir(path)                        #获取所有的文件列表
for f in file_list:
    if os.path.isdir(path + f):                     #判断是否文件夹的方法(注意输入值是路径+文件本身)
        print("这是文件夹" + os.getcwd() + "\\" + f)
    if os.path.isfile(path + f):                    #判断是否是文件
        print("这是文件" + os.getcwd() + "\\" + f)

面向对象:封装基础知识

注意类中的两大基础对立组合
类属性、对象属性(class=、self.class=)
类方法、对象方法(@classmethod def(cls)、def(self))

所有对象共享类属性、而每个类属性都只有唯一一个
所有对象的对象属性都独立
类方法可以直接用类来引用,对象方法必须得从实例化的对象中引用

三大隐式调用的自带函数__start__、__init __、__del __
(注意__start__是初始化函数、__init__是构造函数,
严格来说这两个合在一起才是“构造函数”,但__start__很少用)

以及一个少用的@staticmethod静态方法

#类的封装:基础方法
#基础方法有两个:__init__、__del__
#一个会在初始化类时自动使用,一个会在对象“生命周期结束时”自动使用
class Apple:
    def __init__(self):
        print("初始化函数__init__")

    #小细节1:定义类时,函数与函数之间要空一行
    #小细节2:每一个类中的方法都有一个叫 self 的输入值
    def __del__(self):
        print("析构函数__del__")

a = Apple()


#类的封装:self
#self代表“当前所有对象”,可以使用这个来内部访问所有变量/方法
#所有函数都以self为第一个参数
class Apple:
    name = "apple"
    def get_name(self):
        print(self.name)    #用self访问变量的例子

    def display(self):
        self.get_name()     #用self访问函数

Apple().display()       #直接使用类名来使用方法
                        #注意:类名后面有括号(),即代表“这是一个对象”
                        #在此基础上使用方法,都是通过对象来使用

#封装:__new__
#基础方法之一,这个才是真正的“构造函数”,init只是“初始化函数”
#严格意义上来说,new 和 init 合在一起才是完整的构造函数,

#一般不会手动去写__new__
#三个基础函数中,使用频率为:init > new > del
class Apple:
    def __new__(cls):
        return super().__new__(cls)
        #注意上方的cls,这代表了当前这个新建的类,
        #由于当前没有初始化完成,所以self现在还用不了

        #同时,其中还出现了super(),这表示“使用基类”

    def __init__(self):
        print("初始化函数__init__")

    def __del__(self):
        print("析构函数__del__")

a = Apple()     #此处的运行结果展示了三个基础函数的使用顺序
                #①new、②init、③del


#封装:类属性
#特点是“全局,唯一”
#能被类名直接使用,也能被对象使用,结果都会得到保存
#注意:如果使用“不可变的类型”(如字符串、数字),会看不出来保存了的效果
    #推荐使用列表、键值对等数据来当类属性
class Apple:
    name = "tom"
    l = [1, 2, 3]   #全局、唯一

a = Apple()
print("对比:修改类属性的值,对于不可改值的str又会怎样")
print(id(Apple.name))
print(id(a.name))

a.name = "jack"
a.l += [4, 5, 6,]

print(id(Apple.name))       #两次id的对照可以看出
print(id(a.name))           #对于可变类型,“类属性”的更改确实可以被类、对象1、对象2访问


#封装:类属性的操作
#操作类属性时,只用在 类属性前+类名
#此例子展示的是:每次新建对象时,使一个类属性+1
class Student:
    count = 0
    def __init__(self):
        Student.count += 1

    @classmethod    #@:一个"装饰器"
                    #classmethod:在此处的用法是,使这个方法变为“类方法”(不常用)
    def get_count(self):
        print("共有%d个学生" % Student.count)

s1 = Student()
s2 = Student()

Student.get_count()  #结果为count=2
                     #定义为类方法,即可像这样直接通过类名来引用


#封装:对象属性
#类中的属性分为两种:类属性、对象属性
#对象属性即“只能被实例化的对象访问的属性”
class A:
    def __init__(self, name = "Jerry", age = 18):  #初始化的参数也可以有默认值
        #声明对象属性,对象属性只能在方法中声明
        #同时、对象属性在init中声明,最方便后续使用
        self.name = name
        self.age = age

a1 = A("tom", 18)
print(a1.name)
print(a1.age)

a2 = A()
print(a2.name)
print(a2.age)       #对比可得,对象属性的不同之处


#封装:修饰器
class A:
    #修饰器property把一个方法变成属性调用
    @property
    def counter(self):
        return 10000

a = A()
print(a.counter)        #可以作为一个变量直接使用


#封装:公有与私有(以__开头)
#默认情况下都是共有属性/方法
#加上__、外部就不能“直接”访问
class Apple:
    i = 100         #公有变量
    __j = 1000      #私有成员变量,外部不能访问
    def test1(self):
        print(self.i, "内部输出")
        print(self.__j, "内部输出")      #内部想用私有变量,没有问题
        self.__test2()              #内部想用私有方法,没问题
        print("Apple.test1()")

    def __test2(self):
        print("Apple.__test1()")
a = Apple()
print(a.i , "外部输出")
a.test1()       #借由方法的内部引用,我们可以读取到私有的属性和方法

#封装,私有实现揭秘1
#实际上Python做不到真的“私有”,它只是用一种特殊方法把属性/方法换了个名字
class A:
    __name1 = "Tom"
    def __test1(self):
        self.__name2 = "Jerry"
        print("__test1")

a = A()
#用“对象名._类名__私有名”,就可以使用私有化的属性/方法了
a._A__test1()
print(a._A__name1)
print(a._A__name2)


#封装:私有化实现揭秘2
class Apple:
    __name = "tom"          #私有类属性
    def __init__(self):
        self.__age = 18     #私有对象属性

    def __test(self):       #私有函数
        print("__test()")

a = Apple()
a._Apple__test()            #私有函数访问方式
print(a._Apple__name)       #私有成员变量访问方式
print(a._Apple__age)        #私有属性访问方式


#属性总体练习
#尝试使用__dict__,将所有属性以键值对的形式输出
class Apple:
    count = 0       #类属性
    def __init__(self,name,age,address):
        self.name = name        #对象属性
        self.age = age          #对象属性
        self.address = address  #对象属性
        Apple.count += 1        #每有一个新对象初始化时,类属性count+=1(计算实例化了多少个类)
    def display(self):
        print("我叫%s,今年%d岁,我来自%s。" % (self.name, self.age, self.address))

a1 = Apple("Tom" , 18 ,"USA")
a1.display()
a2 = Apple("jerry", 19, "USA")
print(a1.count)         #访问类属性,其数值会统一发生变化

print(a1.__dict__)   #此处输出结果为:a1中所有可以访问的属性
print(a2.__dict__)   #此处输出结果为:a2中所有可以访问的属性
print(A.__dict__)   #此处输出结果为:类A中所有可以访问的属性

#封装扩展:类方法,纯扩展,不常用
class Apple:
    #类方法(属于类,不属于对象)
    @classmethod
    def test(cls):
        print("ClassMethod")

#类.方法名() 或者 对象.方法名()都可以访问类方法
Apple.test()
a = Apple()
a.test()        #在这一部分中,请感受,类属性/对象属性和类方法/对象方法 的不同


#封装拓展:静态方法(生命周期长)
class Apple:
    #静态方法:寄居在类中,独立存在,其中不能调用对象方法和类方法(类名.方法名()除外)
    @staticmethod
    def test():
        print("ClassMethod")

#类.方法名()  可以访问静态方法
Apple.test()        #不用实例化,直接使用

对对象属性,类属性,继承的总体练习
注意:
#在父类进行初始化时,通过引入参数(父类的init),对其对象属性进行设置
为什么不能修改父类的类属性?
为什么不能单个修改父类的对象属性:因为就是不能,要子类自己重写,覆盖父类的对象属性

#水果类、和他的两个苹果、香蕉子类
#两个水果子类有专属方法,卖()、吃()

class Furit:
    sum = 0     #水果的总数

    def __init__(self, weight = 0, color = "无", place = "未知"):  #给水果父类设置默认值
        self.weight = weight
        self.color = color
        self.place = place  #产地

        Furit.sum += 1  #每新建一个“水果”,"水果"总量+1

class Apple(Furit):
    def __init__(self, price = 0, content = "normal"):
        self.price = price      #价格
        self.content = content   #好吃程度

        #设置父类属性
        super(Apple, self).__init__(20, "red", "佛罗里达州")    #在父类进行初始化时,通过引入参数,对其对象属性进行设置
                                                              #为什么不能修改父类的类属性?
                                                              #为什么不能单个修改父类的对象属性:因为就是不能,要用自己重写

    def buy(self):
        return self.price

    def eat(self):
        return self.content
class Banana(Furit):
    def __init__(self, price = 0, content = "normal"):
        self.price = price  #价格
        self.content = content  #好吃程度

        #设置父类属性
        super(Banana, self).__init__(40, "yellow", "密西西比州")

    def buy(self):
        return self.price

    def eat(self):
        return self.content

a = Apple(10, "好吃")
print("水果的总数", a.sum)       #这个是父类的类属性
print("苹果的产地:", a.place)
print("苹果的重量:", a.weight)       #这两个是父类的对象属性
print("苹果的好吃程度:", a.eat())      #这个是自己的方法访问自己的对象属性

b = Banana(50, "稍甜")
print("水果的总数", b.sum)       #"水果"的总数随着新水果的建立而增多
print("香蕉的产地:", b.place)
print("香蕉的重量:", b.weight)
print("香蕉的价格:", b.buy())


#随机4位生成验证码,但是在类里
from random import randint
class RanCode:
    def get_codes(self, l): #参数l决定需要的随机数大小
        codes = ""
        #使用字符串索引,直接获取值
        s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
        for i in range(0, l):       #注意range为左闭右开区间
            code = s[randint(0, len(s) - 1)]
            codes += code
        return codes

r = RanCode()
print(r.get_codes(4))


#猜随机数游戏,但是在类里
class Random_Guess_number:
    def __init__(self):
        self.targetNumber = randint(0, 100)   #目标
        self.massage = "猜字游戏!猜一个100以内的数?"
        #massag:需要输出的信息,外部会持续输出这个值,内部值更改这里 就可以改变输出
        self.chance = 0     #猜的次数

    def guess_time(self, i):
        self.chance += 1
        if i == self.targetNumber:
            self.massage = "猜中了!!!!一共猜了%d次!" % self.chance
            return "win"            #通过函数返回值来判断输赢
        elif i < self.targetNumber:
            self.massage = "比目标值小,往大了猜"
            self.save_chance(i)     #福利机会,当猜错两次时,会给出与目标值的距离
            return "mini"
        else:
            self.massage = "比目标值大,往小了猜"
            self.save_chance(i)
            return "huge"

    def save_chance(self, now_number):
        if(self.chance != 0 and self.chance % 2 == 0):
            print("特别福利!现在距离目标值还差 %d 个数左右" % abs(now_number - self.targetNumber))
            #abs函数:即绝对值函数

    def unite(self):
        while True:
            print(self.massage)  # 展示需要输出的信息
            guess = int(input("来,猜个数"))  # 记录输入值

            if self.guess_time(guess) == "win":  # 通过函数返回值来判断输赢
                print(self.massage)
                break



r = Random_Guess_number()

r.unite()

文件操作+类的封装

os.listdir():获取输入值中的所有目录
os.path.exists():检查输入值的在当前目录是否已经存在
os.mkdir():创建新文件夹

open():打开文件,有多种打开模式,"r"读、"w"写(覆盖)、“a”(追加)、“rb”(二进制读)、“wb”(二进制写)。此方法需要存入变量中才能正常使用

# update1:把项目封装到类里
# update2:当未排序完成时,提示使用顺序

# 文件分类任务:将多个文件、根据文件名备份到对应文件夹,并对备份的文件重命名为原文件名+时间的模式
# DocumentClassify方法:给定:输入文件夹、输出文件夹;使用下文两个方法进行排序
# classify方法:遍历所有文件,根据文件后缀的不同,创建多个文件夹,同时建立一个“集合”(不能重复)储存所有不同后缀文件夹
#            根据后缀,将备份放入不同文件夹,同时给后缀加上时间标志
# showList方法:展示输出文件夹状态
import time
import os


class DocumentClassify:
    documentType = set()  # 文件属性集合,创建空集合只能这样。不能使用 = {},因为={}是字典专属的方法

    def __init__(self, chaos_path, classify_path):
        self.chaosPath = chaos_path   # 待排序文件夹
        self.classifyPath = classify_path    # 输出文件夹
        self.chaosPathList = os.listdir(self.chaosPath)  # 获取混乱文件夹列表下的所有文件,放入列表

    def classify(self):
        for i in self.chaosPathList:  # 抓取待排序文件夹列表
            if not os.path.exists(self.classifyPath + "/" + i[i.rfind(".") + 1:]):  # 检查是否已经存在此种文件夹
                DocumentClassify.documentType.add(i[i.rfind(".") + 1:])  # 向“文件种类”集合中添加不同的文件种类
                os.mkdir(self.classifyPath + "/" + i[i.rfind(".") + 1:])  # 有新的种类被发现,创建对应的文件夹

            for j in DocumentClassify.documentType:  # 按照“文件种类”分类
                if j == i[i.rfind(".") + 1:]:  # 当文件种类匹配时,进行备份操作
                    old_file = open(self.chaosPath + "/" + i, "rb")
                    new_file_name = \
                        i[0: i.rfind(".")] + \
                        str(time.strftime("%Y%m%S", time.localtime())) + \
                        i[i.rfind("."):]
                    # 新文件名: 原文件名 + 格式化时间 + 原后缀
                    new_file = open(self.classifyPath + "/" + j + "/" + new_file_name, "wb")
                    # 新文件位置:分类文件夹 / 文件种类 / 新文件名
                    new_file.write(old_file.read())  # 读完就写

    def show_list(self):
        classify_path_list = os.listdir(self.classifyPath)  # 获取整理好的分类文件夹目录
        if classify_path_list:
            for i in classify_path_list:
                son_path = os.listdir(self.classifyPath + "/" + i)  # 获取所有“文件类型”子目录
                print("文件夹名", i, ":", end="")
                for j in son_path:
                    print(j + "、", end="")  # 按照格式输出
                print()
        else:
            print("分类文件夹为空,请先使用classify()进行排序")


classify = DocumentClassify("混乱文件夹", "分类文件夹")
classify.classify()
classify.show_list()
print(classify.documentType)

高级特性(列表生成式、错误处理)

#列表生成式基本写法
list = [1, 2, 3]
print([i for i in list])
#列表生成式,待条件
print([i *3 for i in [1, 2, 3] if i >= 2])

print({ i : i*2 for i in [1, 2, 3]})
#异常检测:try与except
#实际使用中,应该避免在写try写很多东西,因为效率会很低
try:
    i1 = int(input("请输入一个值"))
    i2 = int(input("请输入第二个值"))
    print("%d / %d = %0.2f" % (i1, i2, (i1 / i2)))
except :
    print("warning!warning!")


# 完整的try except else finally
try:
    10 * (1 / 0)
except ZeroDivisionError as error:
    # 上面是:except 错误状态 as 存放错误码的地方
    print(error) # 输出错误码
    print("有异常的时候会执行的部分")
else:
    print("没有异常时,执行的代码")
finally:
    print("这句话,有没有异常")


# 线程: 多线程使用
import time
import threading


def display(count):
    for i in range(1, count):
        print(i, end="")
        time.sleep(1)


for i in range(3):
    s = threading.Thread(target=display, args=(5,))
    # 启动线程,target是函数名,args是参数,为了防止有多个参数,多余的逗号必须留
    # 我们在“Python”这个进程中,新建了“s”这几个线程
    s.start()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值