文章目录

  • 文件IO
  • pymysql
  • 格式化日期字符串
  • 函数
  • 面向对象
  • 异常


文件IO

# 文件IO
# open函数:
# 读文件
fr = open("data/students.txt", mode='r', encoding='utf8')
print(fr.read(5))  # read(n) 表示读n个字符
print(fr.readline())  # readline 读一行
print(fr.readlines())  # readlines 读所有的行 并构成list返回

fr.close()

# 写文件:
fw = open("data/newStu.txt", mode='w', encoding='utf8')
# 换行需要手动加上 \n
fw.write("必须传入字符串1\n")
fw.write("必须传入字符串2\n")
fw.write("必须传入字符串3\n")
fw.close()

# with open 不需要手动的关闭文件
# 读取 students.txt的数据并写入newStu2.txt
with open("data/students.txt",mode="r",encoding="utf8") as r1:
    with open("data/newStr2.txt",mode="w",encoding="utf8") as w1:
        w1.writelines(r1.readlines())

pymysql

# 操作MySQL
# pip install pymysql
import pymysql

# 创建连接
conn = pymysql.connect(user='root', passwd='123456', host='master', port=3306, database='student')

# 创建游标 类似statement
cursor = conn.cursor()
# 返回最后查询出来的条数
t = cursor.execute("select id,name,age from student where clazz like %s and gender=%s", ('理科%', '男'))
print("总计记录数:", t)
# print(cursor.fetchone())  # 返回一条记录
# print(cursor.fetchmany(3))  # 返回n条记录
# print(cursor.fetchall())  # 返回所有记录 注意使用

# 循环打印
for i in range(t):
    print(cursor.fetchone())
# 关闭连接
cursor.close()
conn.close()

with pymysql.connect(user='root', passwd='123456', host='master', port=3306, database='student') as conn:
    with conn.cursor() as cursor:
        nums = cursor.execute("select * from student where age>%s", 23)
        for i in range(nums):
            print(cursor.fetchone())
        # conn.rollback() # 发生错误进行回滚
        # conn.commit() # 没有异常直接提交

格式化日期字符串

# 格式化日期字符串
from datetime import datetime

# 字符串转datetime
dt = datetime.strptime("2021-12-07 16:41:38", "%Y-%m-%d %H:%M:%S")
print(dt, type(dt))

print(dt.year)
print(dt.month)
print(dt.day)
print(dt.weekday())

# datetime转字符串
# 2021/12/07 16:41:38
date_str = datetime.strftime(dt, "%Y/%m/%d %H:%M:%S")
print(date_str, type(date_str))

函数

# 函数
"""
# 不需要访问权限修饰符
# 也不需要返回值类型
def 函数名(参数1,参数2......):
    代码块
    代码块
    代码块
    代码块
    # 如果需要返回值
    return 返回值
"""

# 计算1~n的和
def sum1(n):
    sum = 0
    for i in range(1, n + 1):
        sum += i
    return sum

res = sum1(100)
print(res)

# 计算N的阶乘
# 5!=5*4*3*2*1
# 两种方式:
# 1、循环
def jieCheng(n):
    res = 1
    for i in range(1,n+1):
        res *= n
        n -= 1
    return res
    
print(jieCheng(5))

# 2、递归函数
# 尽量避免使用递归函数 能用循环就用循环
# 递归函数需要满足两个条件:
# 自己调用自己
# 停止条件

# 5! = 5 * 4!
# 4! = 4 * 3!
# n! = n * (n-1)!
def jieCheng2(n):
    if n == 1:
        return 1
    return n * jieCheng2(n - 1)

print(jieCheng2(5))

# print(jieCheng2(999)) # 超过最大的递归次数会报错
'''
 匿名函数
 lambda 表达式
 lambda 参数1,参数2......:返回值
'''
# 计算x的y次方
def ciFang(x, y):
    return x ** y
print(ciFang(2, 3)) #8

n1 = lambda x, y: x ** y
print(n1(2, 3)) #8

'''
# 函数参数的类型
# 位置参数(必选参数)、默认参数、可变参数、关键字参数、命名关键字参数
'''

# 默认参数 y
# 计算x的y次方 如果不传入y则默认计算x的2次方
def cifang2(x, y=2):
    return x ** y

# print(ciFang(2))
print(cifang2(2))
print(cifang2(2, 3))

'''
# 可变参数
# 传入n1就 返回n1
# 传入n1,n2 就 返回n1+n2
# 传入n1,n2,n3 就 返回n1+n2+n3
# 传入n1,n2,......,nn 就 返回n1+n2+n3+......+nn
'''

def sumN(*args):
    # args是参数名
    # 要操作传入的参数 可以对args(相当于有参数构成的tuple)进行遍历
    print(args, type(args))
    sum = 0
    for i in args:
        sum += i
    print(sum)

sumN(1)
sumN(1, 2)
sumN(1, 2, 3)
sumN(1, 2, 3, 4)
sumN(1, 2, 3, 4, 5, 6, 7, 8, 9)

# 关键字参数
# 注册函数:
# name、age、addr(可选)、phone(可选)
def register(name, age, **kw):
    print(kw, type(kw))

register("张三", '20', addr="大别野", phone="18888888888")

# 命名关键字参数
# name、age、gender(必选)、addr(可选)、phone(可选)
def register2(name, age, **kw):
    if 'gender' in kw.keys():
        print(kw, type(kw))
    else:
        print("请必须输入您的性别")

register2("李华", '22', addr="乡间小草屋", gender='男')

def register3(name, age='18', *args, gender, **kw):
    print(name, age, args, gender, kw)

register3("小红", '18', gender='女')
register3("小红", '18', 1, 2, 3, 4, 5, 6, 7, gender='女')

面向对象

# 面向对象
# 封装、继承、多态

# 定义类
# 封装方法和变量(属性)
# object是所有类的基类 相当于Java中的Object
class Person(object):
    # 构造函数
    # 类中所有的方法的第一个参数都是self:代表对象本身 相当于Java中的this
    def __init__(self, id, name, gender):
        # 定义了类的属性并进行赋值
        self.id = id
        self.name = name
        self.gender = gender
        # 如果定义的属性不想被直接获取 可以在命名的时候以两个下划线开头
        self.__secret = '这是一个秘密'

    def info(self):
        print("Person", self.id, self.name, self.gender)

    def run(self):
        print("我会跑")

    # 相当于Java中的toString方法 在使用print函数打印该类的对象时会自动调用
    # 重写object中的方法
    def __str__(self):
        return "Person类的对象 %s" % self.name


# 创建对象
zs = Person('001', '张三', '男')
print(zs)
print(zs.id)
print(zs.name)
print(zs.gender)
# print(zs.__secret) # 不能直接获取 相当于进行了 "封装"
# Python中没有严格意义上的封装 更多地是靠编程者良好的编程习惯去约束
# 还是可以通过 _类名+属性名 去将隐藏的属性取出来
print(zs._Person__secret)

zs.info()


class Teacher(Person):
    def __init__(self, id, name, gender):
        # 调用父类的构造方法
        super(Teacher, self).__init__(id, name, gender)
        self.professional = 'compute'

    def info(self):
        print("Teacher", self.id, self.name, self.gender, self.professional)


t1 = Teacher("张老师", "24", "男")
print(t1.id)
print(t1.name)
print(t1.professional)
t1.info()
t1.run()


class Student(Person):
    def __init__(self, id, name, gender):
        # 调用父类的构造方法
        super(Student, self).__init__(id, name, gender)
        self.skill = 'play game'

    def info(self):
        print("Student", self.id, self.name, self.gender, self.skill)

    def run(self):
        print("我跑的很快")


stu1 = Student("李四", "20", "男")


# 定义一个方法接收Person类型的参数 然后对run方法调用两次
# 多态:父类引用指向子类对象
def runTwice(person: Person):
    person.run()
    person.run()


runTwice(zs)
runTwice(t1)
runTwice(stu1)


# 鸭子类型:只要长得像鸭子那么就是鸭子
# 更多的是关注变量有没有方法 并不会对变量做类型的检查
class Duck():
    def run(self):
        print("鸭子也会跑")


dk = Duck()

runTwice(dk)


class Dog():
    pass


dog = Dog()


def run():
    print("狗也会跑")


# 猴子补丁
dog.run = run

runTwice(dog)

异常

a = 1
print(a)
# str1 = 'abc # 语法错误

# 六大常见的异常
# ZeroDivisionError 除零异常
# print(10/0)

# NameError 名称异常
# 变量、函数未定义就使用
# print(i)

# TypeError 类型异常
# print(10+"分") # 在python中int不能跟字符串直接相加

# ValueError 值异常
print(int("123"))
# print(int("abc"))

# IndexError 索引异常
list1 = [1, 2, 3]
print(list1[0])
print(list1[1])
print(list1[2])
# print(list1[3])

# AttributeError 属性异常
str1 = 'abcdef'
# str1.xxxx


# 异常处理
'''
try:
    可能会发生异常的代码
    可能会发生异常的代码
    可能会发生异常的代码
except 异常1:
    异常1发生了该怎么办
except 异常2:
    异常2发生了该怎么办
......
else:
    没有发生异常就会执行
finally:
    不管有没有发生异常都会执行   
'''

try:
    print("start")
    print(10 / 0)
    print("end")
# except Exception as e:
#     print(e)
except ZeroDivisionError as e:
    print(e)
    print("请检查除数")
except ValueError as e:
    print(e)
    print("如果发生了值异常该怎么处理")
else:
    print("没有发生异常就会执行")
finally:
    print("不管有没有发生异常都会执行")


# 自定义异常
class AlienError(Exception):
    pass


age = int(input("请输入一个年龄:"))
# 判断是否成年
# 如果年龄不在0~200范围内直接抛出外星人异常
try:
    if age < 0 or age > 200:
        # print("年龄不符合规范")
        raise AlienError("发生了外星人异常")
    elif age >= 18:
        print("成年")
    elif age < 18:
        print("未成年")
except AlienError as e:
    print("捕获到了AlienError异常")
    print(e)