python语法入门到面向过程编程(三)

函数

1、什么是函数?
在程序中,函数就具备某一功能的工具
事先将工具准备好即函数的定义
遇到应用场景拿来就用即函数的调用
所以务必记住:函数的使用必须遵循先定义,后调用的原则

2、为何要用函数,不用函数问题是:
1、程序冗长
2 程序的扩展性差
3 程序的可读性差

3 如何用函数:
函数的使用必须遵循先定义,后调用的原则
‘’’
def 函数名(参数1,参数2,…):
‘’’
函数功能的描述信息
:param 参数1: 描述
:param 参数2: 描述
:return: 返回值
‘’’
代码1
代码2
代码3

return 返回值

def register():
    while True:
        uname=input('username>>:').strip()
        if uname.isalpha():
            break
        else:
            print('用户名必须由字母组成傻叉')

    while True:
        pwd1=input('密码>>: ').strip()
        pwd2=input('重复输入密码>>: ').strip()
        if pwd1 == pwd2:
            break
        else:
            print('两次输入的密码不一致')

    with open('db.txt','at',encoding='utf-8') as f:
        f.write('%s:%s\n' %(uname,pwd1))
        f.flush()
def auth():
    认证功能
    inp_uname=input('请输入你的账号:').strip()
    inp_pwd=input('请输入你的密码:').strip()
    with open('db.txt','rt',encoding='utf-8') as f:
        for line in f:
            info=line.strip('\n').split(':')
            if inp_uname == info[0] and inp_pwd == info[1]:
                print('login successfull')
                break
        else:
            print('账号或密码错误')

拿来就用=>函数的调用阶段
print(register)
register()
auth()
register()
register()
register()
函数的使用必须遵循先定义,后调用的原则,
没有事先定义函数,而直接引用函数名,就相当于在引用一个不存在的变量名

1、函数定义阶段:只检测函数体的语法,不执行函数体代码
def func():
print(‘1111’)
print(‘222’)
print(‘333’)

2、函数调用阶段:执行函数体代码
func()

例1

 def foo():
     print('from foo')
      bar()

 foo()

例2

 def bar():
     print('from bar')

 def foo():
     print('from foo')
     bar()

 foo()

例3

 def foo():
     print('from foo')
     bar()

 def bar():
     print('from bar')

 foo()

例4

 def foo():
     print('from foo')
     bar()
 foo()
 def bar():
     print('from bar')

定义函数时的参数就是函数体接收外部传值的一种媒介,其实就一个变量名

1、无参函数:
在函数定义阶段括号内没有参数,称为无参函数
注意:定义时无参,意味着调用时也无需传入参数
应用:
如果函数体代码逻辑不需要依赖外部传入的值,必须定义无参函数

 def func():
     print('hello world')
 func()

2、有参函数
在函数定义阶段括号内有参数,称为有参函数
注意:定义时有参,意味着调用时也必须传入参数
应用:
如果函数体代码逻辑需要依赖外部传入的值,必须定义成有参函数

 def sum2(x,y):
      x=10
      y=20
     res=x+y
     print(res)
 sum2(10,20)
 sum2(30,40)


def check_user():
    while True:
        uname=input('username>>:').strip()
        if uname.isalpha():
            return uname
             break
        else:
            print('用户名必须由字母组成吊毛')


def check_pwd():
    while True:
        pwd1=input('密码>>: ').strip()
        pwd2=input('重复输入密码>>: ').strip()
        if pwd1 == pwd2:
            return pwd1
        else:
            print('两次输入的密码不一致')


def db_hanle(uname,pwd1):
    with open('db.txt','at',encoding='utf-8') as f:
        f.write('%s:%s\n' %(uname,pwd1))
         f.flush()
         

def register():
     检测用户名是否合法
    x=check_user() x='isetan'
     检测密码是否合法
    y=check_pwd() y='123'

     写入数据文件
     db_hanle(合法的用户名,合法的密码)
    db_hanle(x,y)
register()

3、空函数

 def func():
     pass
 def check_user():
     pass
 def check_pwd():
     pass
 def write_db(x,y):
     pass
 def register():
    1 输入用户名,并进行合法性校验
    2 输入密码,并进行合法性校验
    3 将合法的用户名、密码写入文件
     x=check_user()
     y=check_pwd()
     write_db(x,y)

定义函数时的参数就是函数体接收外部传值的一种媒介,其实就一个变量名

1、什么是返回值
返回值是一个函数的处理结果,

2、为什么要有返回值
如果我们需要在程序中拿到函数的处理结果做进一步的处理,则需要函数必须有返回值

3、函数的返回值的应用
函数的返回值用return去定义
格式为:
return 值

注意:
    1、return是一个函数结束的标志,函数内可以有多个return,
        但只要执行一次,整个函数就会结束运行

    2、return 的返回值无类型限制,即可以是任意数据类型
    3、return 的返回值无个数限制,即可以用逗号分隔开多个任意类型的值
        0个:返回None,ps:不写return默认会在函数的最后一行添加return None
        1个:返回的值就是该值本身
        多个:返回值是元组
 def foo():
     print(1)
     print(2)
     print(3)
     return [1,2,3],'a',('a','b'),{1,2}
     print(4)
     print(5)
     print(6)

 res=foo()
 print(res)


 def bar():
     print(1)
     print(1)
     print(1)
     print(1)
     return
     print(2)
     print(3)
     print(4)

 res=bar()
 print(res)

‘’’
1 什么是调用函数
函数名(…)即调用函数,会执行函数体代码,直到碰到return结束或者一直运行完毕所有代码

2 为何要调用函数
用函数的功能

3、函数调用分为三种形式

x=3000
y=2000
def max2(x,y):
    if x > y:
        return x #return 3000
    else:
        return y #reuturn 2000

res=max2(3000,2000)

annual_salary=res * 12

print(annual_salary)

max2(1,2)
res=max2(3000,2000) * 12
res=max2(max2(1000,2000),3000)

def foo():
 print(1)
 print(2)
 print(3)
 return None
res=foo()
print(res)


def max2(x,y):
    if x > y:
        return x
    else:
        return y

形式一:
max2(1,2)

形式二:
res=max2(3000,2000) * 12
print(res)

形式三:
res=max2(max2(1000,2000),3000)
print(res)

总的分类:
1、形参:在函数定义阶段括号内定义的参数,称之为形式参数,简称形参,本质就是变量名

 def foo(x,y): #x=1,y=2
     print(x)
     print(y)

2、实参:在函数调用阶段括号内传入的值,称之为实际参数,简称实参,本质就是变量的值
foo(1,2)

详细的分类:
一、位置参数:
位置形参:在函数定义阶段,按照从左到右的顺序依次定义的形参,称之为位置形参
特点:但凡是按照位置定义的形参,都必须被传值,多一个不行,少一个也不行
def foo(x,y):
print(‘x:’,x)
print(‘y:’,y)

位置实参:在函数调用阶段,按照从左到右的顺序依次定义的实参,称之为位置实参
特点:按照位置为对应的形参依次传值
foo(1,2)
foo(2,1)

二、关键字实参:在调用函数时,按照key=value的形式为指定的参数传值,称为关键字实参
特点:可以打破位置的限制,但仍能为指定的形参赋值
foo(y=2,x=1)

注意:
1、可以混用位置实参与关键字实参,但位置实参必须放在关键字实参的前面
foo(1,y=2)
foo(y=2,1) SyntaxError: positional argument follows keyword argument

2、可以混用,但不能对一个形参重复赋值
foo(1,y=2,x=10)

三:默认参数:在函数定义阶段,就已经为形参赋值,该形参称为默认形参
特点:在定义阶段就已经被赋值,意味着在调用可以不用为其赋值

 def foo(x,y=10):
     print('x:',x)
     print('y:',y)
 foo(1)
 foo(1,3)

注意:
1、位置形参必须放到默认形参的前面,否则报语法错误
def foo(x=1,y):
pass
2、默认参数的值只在定义阶段赋值一次,即默认参数的值在函数定义阶段就已经固定死了

 m=10
 def foo(x=m,y=11):
     print(x)
     print(y)
 m=1111111111111111111111111111111111111111111111111111111111
 foo()

3、默认参数的值通常应该定义不可变类型

def register(name,hobby,hobbies=[]):
     hobbies.append(hobby)
     print('%s的爱好' %name,end=':')
     print(hobbies)

 register('isetan','play')
 register('axxx','piao')
 register('lxx','烫头')

 def register(name,hobby,hobbies=None):
     if hobbies is None:
         hobbies=[]
     hobbies.append(hobby)
     print('%s的爱好' %name,end=':')
     print(hobbies)

 register('isetan','play')
 register('axxx','piao')
 register('lxx','烫头')

总结:

形参的应用:
1、位置形参:大多数情况下的调用值都不一样,就应该将该参数定义成位置形参
2、默认形参:大多数情况下的调用值都一样,就应该将该参数定义成默认形参

 def register(name,age,sex='male'):
     print(name)
     print(age)
     print(sex)

 register('isetan',18,)
 register('大脑门',73,'female')
 register('小脑门',84,)
 register('大高个',18,)

四:可变长参数:指的是在调用函数时,传入的参数个数可以不固定
而调用函数时,传值的方式无非两种,一种位置实参,另一种时关键字实参
所以对应着,形参也必须有两种解决方案,来分别接收溢出的位置实参(*)与关键字实参(**)

1、形参中某个参数带形参中的会将溢出的位置实参全部接收,然后存储元组的形式,然后把元组赋值给*后的变量名

def foo(x,y,*z): x=1,y=2,z=(3,4,5,6,7)
     print(x)
     print(y)
     print(z)
 foo(1,2,3,4,5,6,7)

应用

 def my_sum(*nums):
     res=0
     for num in nums:
         res+=num
     return res
 print(my_sum(1,2,3,4,5))

2、实参中的参数也可以带实参中带会将该参数的值循环取出,打散成位置实参
ps:以后但凡碰到实参中带
的,它就是位置实参,应该立马打散成位置实参去看

def foo(x,y,z):
     print(x,y,z)

 foo(1,*[2,3]) foo(1,2,3)
 foo(1,*'he') foo(1,'h','e')
 foo(1,*(2,3,4)) foo(1,2,3,4)

 def foo(x,y,z,*args):
     print(x)
     print(y)
     print(z)
     print(args)

 foo(1,2,3,4,5,6,7,*[8,9,10,11]) foo(1,2,3,4,5,6,7,8,9,10,11)

注意:约定俗成形参中的*变量名的写法都是:*args

1、形参中某个参数带**
形参中的会将溢出的关键字实参全部接收,然后存储字典的形式,然后把字典赋值给后的变量名

def foo(x,y,**z): x=1,y=2,z={'c':5,'b':4,'a':3}
     print(x)
     print(y)
     print(z)
 foo(1,2,a=3,b=4,c=5)

2、实参中的参数也可以带**,该参数必须是字典
实参中带**,会将该参数的值循环取出,打散成关键字实参,ps:以后但凡碰到实参中带的,它就是关键字实参,应该立马打散成关键字实参去看

def foo(x,y,z):
     print(x)
     print(y)
     print(z)

 foo(1,2,**{'a':1,'b':2,'c':3,'z':3}) foo(1,2,c=3,b=2,a=1,z=3)
 foo(**{'z':3,'x':1,'y':2}) foo(y=2,x=1,z=3)

注意:约定俗成形参中的**变量名的写法都是:**kwargs

 def index(name,age,sex):
     print('welecome %s:%s:%s to index page' %(name,age,sex))

 def wrapper(*args,**kwargs): args=(1,),kwargs={'x': 1, 'y': 2, 'z': 3}
     index(*args,**kwargs) index(*(1,),**{'x': 1, 'y': 2, 'z': 3}) index(1,x=1,y=2,z=3)

 wrapper(name='isetan',sex='male',age=18)

五 命名关键字形参:在函数定义阶段,*后面的参数都是命名关键字参数(**)
特点:在传值时,必须按照key=value的传,并且key必须命名关键字参数指定的参数名

def register(x,y,z,**kwargs): kwargs={'b':18,'a':'isetan'}
     if 'name' not in kwargs or 'age' not in  kwargs:
         print('用户名与年龄必须使用关键字的形式传值')
         return
     print(kwargs['name'])
     print(kwargs['age'])
 register(1,2,3,a='isetan',b=18)

 def register(x,y,z,*args,name='isetan',age):
     print(args)
     print(name)
     print(age)
 register(1,2,3,4,5,6,7,age=18)

 def foo(x,y=1,*args,z=1,a,b,**kwargs):
     pass

 foo(1,*[1,2,3],a=1,**{'x':1,'y':2}) foo(1,1,2,3,a=1,y=2,x=1)
 foo(1,2)
 foo(x=1,y=2)

作用域与闭包函数

作用域关系在函数定义阶段时就已经固定死了,与调用位置无关
即:在任意位置调用函数都需要跑到定义函数时寻找作用域关系

 def f1():
     x=1
     def inner():
         print(x)
     return inner
 func=f1()
 def f2():
     x=111111
     func()
 f2()

闭包函数:
闭指的是:该函数是一个内部函数
包指的是:指的是该函数包含对外部作用域(非全局作用域)名字的引用

def outter():
     x = 1
     def inner():
         print(x)
     return inner
 f=outter()

为函数体传值的方式一:使用参数的形式

 def inner(x):
     print(x)
 inner(1)

为函数体传值的方式二:包给函数

def outter(x):
     x=1
    def inner():
        print(x)
    return inner

f=outter(1)
f()

传值的2种方式一:

 import requests
 def get(url):
     response=requests.get(url)
     if response.status_code == 200:
         print(response.text)
 get('https://www.baidu.com')

 get('https://www.python.org')
 get('https://www.python.org')

传值的2种方式二:

import requests
def outter(url):
     url='https://www.baidu.com'
    def get():
        response=requests.get(url)
        if response.status_code == 200:
            print(response.text)
    return get
baidu=outter('https://www.baidu.com')
python=outter('https://www.python.org')

baidu()
baidu()

python()
python()

装饰器,迭代器

1、有参装饰器

def outter(x):
        def deco(func):
            def wrapper(*args,**kwargs):
                res=func(*args,**kwargs)
                return res
            return wrapper
        return deco


    @outter(x=1) #index=deco(index)
    def index():
        pass
2、迭代器
    1、迭代:是一个重复的过程,每次重复都是基于上一次的结果而来
        迭代器:迭代取值的工具

    2、为什么要用迭代器
        对于没有索引的数据类型,必须找到一种通用的不依赖索引的迭代取值方式

    3、如何用迭代器
        可迭代的对象:但凡内置有__iter__方法的对象都是可迭代的对象
                    迭代器对象=可迭代的对象.__iter__()
        迭代器对象:既内置有__iter__方法,又内置有__next__方法的对象
                    迭代器对象本身=迭代器对象.__iter__()
                    拿到的是下一个值=迭代器对象.__next__()

        ps:迭代器对象一定是可迭代对象

        for i in 可迭代的对象:
            pass


        总结迭代器优缺点:
            优点
                1、节省内存
                2、提供一种不依赖索引的迭代取值方式
                    l=[1,2,3]
                    iter_l=iter(l)
                    next(iter_l)
                    next(iter_l)

            缺点:
                1、取值不灵活,只能往后取不能往前推
                2、无法预测值的个数


            l=[1,2,3,4,....]
            iter_l=iter(l)

生成器

 def func():
        yield
    g=func()
    next(g)

    x=yield
2、三元表达式
    res=x if 条件 else y
3、列表推导式,字典生成式,生成器表达式
    l=[表达式 for i in 可迭代对象 if 条件]
    g=(表达式 for i in 可迭代对象 if 条件)
    d={k:v for i in 可迭代对象 if 条件}
4、max,zip
    max(可迭代对象)
    生成器=zip(可迭代对象1,可迭代对象2)
        g=zip('hello',[1,2,3])
        # print(g)
        print(list(g))

函数递归,又名、无名函数,方法

1 什么是函数递归
函数递归调用(是一种特殊的嵌套调用):在调用一个函数的过程中,又直接或间接地调用了该函数本身

递归必须要有两个明确的阶段:
    递推:一层一层递归调用下去,强调每进入下一层递归问题的规模都必须有所减少
    回溯:递归必须要有一个明确的结束条件,在满足该条件时结束递推
        开始一层一层回溯

递归的精髓在于通过不断地重复逼近一个最终的结果

3、如何用

 import sys
 print(sys.getrecursionlimit())
 sys.setrecursionlimit(3000)
 def foo(n):
     print('from foo',n)
     foo(n+1)
 foo(0)

 def bar():
     print('from bar')
     foo()

 def foo():
     print('from foo')
     bar()

 foo()

 age(5) = age(4) + 2
 age(4) = age(3) + 2
 age(3) = age(2) + 2
 age(2) = age(1) + 2
 age(1) = 26

 age(n) = age(n-1) + 2 n > 1
 age(1) = 26           n = 1


 def age(n):
     if n == 1:
         return 26
     return age(n-1) + 2
 print(age(5))


 l=[1,[2,[3,[4,[5,[6,[7,[8,[9,]]]]]]]]]

 def tell(l):
     for item in l:
         if type(item) is list:
             继续进入下一层递归
             tell(item)
         else:
             print(item)
 tell(l)

有一个从小到大排列的整型数字列表

 nums=[1,3,7,11,22,34,55,78,111,115,137,149,246,371]
 10 in nums
 for item in nums:
     if item == 10:
         print('find it')
         break
 else:
     print('not exists')
     
nums=[1,3,7,11,22,34,55,78,111,115,137,149,246,371]
def search(search_num,nums):
    print(nums)
    if len(nums) == 0:
        print('not exists')
        return
    mid_index=len(nums) // 2
    if search_num > nums[mid_index]:
         in the right
        nums=nums[mid_index+1:]
        search(search_num,nums)
    elif search_num < nums[mid_index]:
         in the left
        nums=nums[:mid_index]
        search(search_num,nums)
    else:
        print('find it')

search(31,nums)

有名函数:基于函数名重复使用

# def func():
#     print('from func')

# func()

匿名函数:没有绑定名字的下场是用一次就回收了

def func(x,y): #func=函数的内存地址
    return x + y
    
res=(lambda x,y:x+y)(1,2)
print(res)

f=lambda x,y:x+y
print(f)
print(f(1,2))

max的工作原理

1 首先将可迭代对象变成迭代器对象
2 res=next(可迭代器对象),将res当作参数传给key指定的函数,然后将该函数的返回值当作判断依据

salaries={
     'xxx':3000,
     'yyy':100000000,
     'zzz':10000,
     'aaa':2000
}
def func(k):
    return salaries[k]
print(max(salaries,key=func)) #next(iter_s)
v1=func('xxx')
v2=func('yyy')
v3=func('zzz')
v4=func('aaa')

print(max(salaries,key=lambda k:salaries[k])) #next(iter_s)
print(min(salaries,key=lambda k:salaries[k])) #next(iter_s)


l=[10,1,3,-9,22]
l1=sorted(l,reverse=False)
print(l1)

l2=sorted(l,reverse=True)
print(l2)

print(sorted(salaries,key=lambda k:salaries[k],reverse=True))


map的工作原理
#1 首先将可迭代对象变成迭代器对象
#2 res=next(可迭代器对象),将res当作参数传给第一个参数指定的函数,然后将该函数的返回值当作map的结果之一
names=['xxx','yyy','zzz','aaa']
aaa=map(lambda x:x+"_SB",names)
print(aaa)
print(list(aaa))

print([name+"_SB" for name in names])



filter的工作原理
#1 首先将可迭代对象变成迭代器对象
#2 res=next(可迭代器对象),将res当作参数传给第一个参数指定的函数,然后filter会判断函数的返回值的真假,如果为真则留下res
names=['xxxSB','yyy','zzzSB','aaaSB']

print([name for name in names if name.endswith('SB')])

aaa=filter(lambda x:x.endswith('SB'),names)
print(aaa)
print(list(aaa))


res='你好'.encode('utf-8')
print(res)

res=bytes('你好',encoding='utf-8')
print(res)
# 参考ASCII表将数字转成对应的字符
print(chr(65))
print(chr(90))
# 参考ASCII表将字符转成对应的数字
print(ord('A'))
print(divmod(10,3))


l=['a','b','c']
for item in enumerate(l):
    print(item)

l='[1,2,3]'
l1=eval(l)
print(l1,type(l1))
print(l1[0])

with open('a.txt',encoding='utf-8') as f:
    data=f.read()
    print(data,type(data))
    dic=eval(data)
    print(dic['sex'])

print(pow(3,2,2)) # (3 ** 2) % 2
print(round(3.3))
print(sum(range(101)))



module=input('请输入你要导入的模块名>>: ').strip() #module='asdfsadf'
m=__import__(module)
print(m.time())



# 面向对象里的重点
classmethod
staticmethod
property
delattr
hasattr
getattr
setattr
isinstance
issubclass
object
super


# 了解
# print(abs(-13))
# print(all([1,2,3,]))
# print(all([]))

# print(any([0,None,'',1]))
# print(any([0,None,'',0]))
# print(any([]))

# print(bin(3)) #11
# print(oct(9)) #11
# print(hex(17)) #11

# print(callable(len))

# import time
# print(dir(time)) #列举出所有:time.名字


# s=frozenset({1,2,3}) # 不可变集合
# s1=set({1,2,3}) # 可变集合

# a=1111111111111111111111111111111111111111111111
# # print(globals())
# # print(locals())
# def func():
#     x=222222222
#     # print(globals())
#     print(locals())
# func()

# hash([1,2,3])

# def func():
#     """
#     文档注释
#     :return:
#     """
#     pass
#
# print(help(func))

# l=['a','b','c','d','e']
# s=slice(1,4,2)
# print(l[1:4:2])
# print(l[s])

# print(vars())

模块

1、什么是模块
模块的一系列功能的集合体
2、为何用模块
拿来(内置或第三方的模块)主义,提升开发效率
自定义模块可以让程序的各部分组件重用模块内的功能
3、如何用模块
大前提:模块是被执行文件导入使用,模块的导入必须搞明白谁是执行文件,谁是被导入的模块

    import
        首次import m1导入模块都发生三件事:
        1、先创建一个模块的名称空间
        2、执行m1.py,将执行过程中产生的名称都放入模块的名称空间中
        3、在当前执行文件中拿到一个名字m1,该名字是指向模块的名称空间的

        使用方法:指名道姓地访问m1名称空间中的名字func,优点是不会与当前名称空间中的名字冲突,缺点是每次访问都需要加上前缀
            m1.func

    from ... import
        首次from m1 import func导入模块都发生三件事:
        1、先创建一个模块的名称空间
        2、执行m1.py,将执行过程中产生的名称都放入模块的名称空间中
        3、在当前执行文件中直接拿到一个功能名func,该名字是直接指向模块名称空间中的某一个功能的


        使用方法:直接使用功能即可,优点是无需加任何前缀,缺点是容易与当前名称空间中的名字冲突
            def func():
                pass
            func()


4、模块的搜索路径
    内存-》内置模块-》sys.path

5、软件开发的目录规范

1、什么是包
1、包
什么是包:包就是一个含有__init__.py文件的文件夹
包是模块的一种形式,即包是用来被导入的,但包的本质就是一个文件夹(文件夹的作用就是用来存放文件的,包内所有的文件都是用来被导入使用的)
import 包
包.名字

    导入方式:
        1、绝对导入: 相对于执行文件所在的文件夹
        2、相对导入:相对于当前被导入的文件(只能用于模块直接的互相导入)
            .

2、如何用包
导入包就是在导包下的__init__.py
import …
from … import…

主义的问题:
    1、包内所有的文件都是被导入使用的,而不是被直接运行的
    2、包内部模块之间的导入可以使用绝对导入(以包的根目录为基准)与相对导入(以当前被导入的模块所在的目录为基准)
        推荐使用相对导入
    3、当文件是执行文件时,无法在该文件内用相对导入的语法
        只有在文件时被当作模块导入时,该文件内才能使用相对导入的语法

    4、凡是在导入时带点的,点的左边都必须是一个包
            import aaa.bbb.m3.f3 # 错误

日志模块logging
1、logger:产生日志
2、filter
3、handler:接收logger对象传来的日志,控制输出到不同的位置
4、formatter:控制handler对象输出日志的格式

    debug 10
    info 20
    warning 30
    error 40
    critical 50

1、序列化/发序列化
内存中的数据—序列化----》中间格式(存到硬盘/基于网络传输)

    json
        优点:
            可以跨平台
        缺点:
            不能识别所有的python类型
    pickle
        优点:
            可以识别所有的python类型
        缺点:
            不可以跨平台

    import json
    dic={'x':1}
    json_str=json.dumps(dic)
    json.loads(json_str)

    with open('db.json','wt',encoding='utf') as f:
        json.dump(dic,f)

    with open('db.json','rt',encoding='utf') as f:
        dic=json.load(f)


2、时间模块
    时间戳time.time()
    格式化的字符串time.strftime('%Y-%m-%d %H:%M:%S')
    结构化的时间time.localtime()  time.gmtime()

    datetime.datetime.now()
    datetime.datetime.fromtimestamp(12313123)
    datetime.datetime.now() + datetime.timedelta(hours=-3)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值