The fifth chapter function

The fifth chapter function

The nature and function of the application scenarios 5.1

Up to now: process-oriented programming (readability poor / poor reusability)

For functional programming:

  1. Nature: the N lines of code to get away and gave him a name, you can be found later by name and code execution
  2. Scenario:
    • Repeat Code
    • Code particularly more than one screen may be selected by the function code divided
# 面向过程编程 
user_input = input('请输入角色:')

if user_input == '管理员':    
    import smtplib    
    from email.mime.text import MIMEText    
    from email.utils import formataddr
    msg = MIMEText('管理员,我想演男一号,你想怎么着都行。', 'plain', 'utf-8')    
    msg['From'] = formataddr(["李邵奇", '[email protected]'])    
    msg['To'] = formataddr(["管理员", '[email protected]'])    
    msg['Subject'] = "亲爱的管理员"
    
    server = smtplib.SMTP("smtp.163.com", 25)           
    server.login("[email protected]", "qq1105400511")          
    server.sendmail('[email protected]', ['管理员', ], msg.as_string())
    server.quit() 
    
elif user_input == '业务员':    
    import smtplib    
    from email.mime.text import MIMEText    
    from email.utils import formataddr
    msg = MIMEText('业务员,我想演男一号,你想怎么着都行。', 'plain', 'utf-8')    
    msg['From'] = formataddr(["李邵奇", '[email protected]'])    
    msg['To'] = formataddr(["业务员", '业务员'])    
    msg['Subject'] = "亲爱的业务员"
    
    server = smtplib.SMTP("smtp.163.com", 25)    
    server.login("[email protected]", "qq1105400511")   
    server.sendmail('[email protected]', ['业务员', ], msg.as_string())    
    server.quit() 
    
elif user_input == '老板':    
    import smtplib    
    from email.mime.text import MIMEText    
    from email.utils import formataddr
    
    msg = MIMEText('老板,我想演男一号,你想怎么着都行。', 'plain', 'utf-8')    
    msg['From'] = formataddr(["李邵奇", '[email protected]'])    
    msg['To'] = formataddr(["老板", '老板邮箱'])    
    msg['Subject'] = "亲爱的老板"
    
    server = smtplib.SMTP("smtp.163.com", 25)    
    server.login("[email protected]", "qq1105400511")    
    server.sendmail('[email protected]', ['老板邮箱', ], msg.as_string())    
    server.quit()
#函数式编程
#先不考虑是否能执行,单纯为了比较函数式编程与面向过程编程的区别
def send_email():    
    import smtplib    
    from email.mime.text import MIMEText    
    from email.utils import formataddr
    
    msg = MIMEText('老板,我想演男一号,你想怎么着都行。', 'plain', 'utf-8')    
    msg['From'] = formataddr(["李邵奇", '[email protected]'])    
    msg['To'] = formataddr(["老板", '老板邮箱'])    
    msg['Subject'] = "情爱的老板"
    
    server = smtplib.SMTP("smtp.163.com", 25)    
    server.login("[email protected]", "qq1105400511")    
    server.sendmail('[email protected]', ['老板邮箱', ], msg.as_string())
    server.quit()

user_input = input('请输入角色:')
if user_input == '管理员':    
    send_email() 
elif user_input == '业务员':    
    send_email() 
elif user_input == '老板':    
    send_email()

5.2 function definition

5.2.1 Basic-defined functions

  1. Basic form

    def 函数名():       #函数的定义
        代码            #函数内容
    
    函数名()            #函数的执行
  2. note

    • If the function is not called, the internal code will never be executed
    • len (calculated length) is a function of the internal written python

5.2.2 parameters (the number is not limited)

5.2.2.1 The basic parameters of knowledge

def get_list_date(aaa):       #aaa:形式参数(形参)  任意个数
    v = [11,22,33,44]
    print(v[aaa])
    
get_list_date(1)             #1:实际参数(实参)   任意类型
  • Send mail problems

    # 假如:管理员/业务员/老板用的是同一个邮箱。 
    def send_email(to):    
        import smtplib    
        from email.mime.text import MIMEText    
        from email.utils import formataddr
    
        msg = MIMEText('导演,我想演男一号,你想怎么着都行。', 'plain', 'utf-8')    
        msg['From'] = formataddr(["李邵奇", '[email protected]'])    
        msg['To'] = formataddr(["导演", to])    
        msg['Subject'] = "情爱的导演"
    
        server = smtplib.SMTP("smtp.163.com", 25)    
        server.login("[email protected]", "qq1105400511")  
        server.sendmail('[email protected]', [to, ], msg.as_string())    
        server.quit() 
    
    def send_email(to):    
        template = "要给%s发送邮件" %(to,)    
        print(template)
    
    user_input = input('请输入角色:')
    if user_input == '管理员':    
        send_email('[email protected]') 
    elif user_input == '业务员':    
        send_email('[email protected]') 
    elif user_input == '老板':    
        send_email('[email protected]')

5.2.2.2 Location parameter passing

  • Parameter passing: call the function and pass parameters
  • Requirements: strict accordance with the position of mass participation
  • Location parameters: positional argument
  • Basic form
def func(a,b):
    print(a,b)
    
func(11,22)               #位置都是一一对应的,a = 11,b = 22

5.2.2.3 key parameter passing

  • Keyword arguments: keyword argument

  • Basic form

    def func(a,b):
        print(a,b)
    
    func(b = 11,a = 22)        #按照关键字进行传参,可以交换位置
  • Note: open (Open File) is a function of the internal python-written, keyword use is the mass participation

  • Keywords mass participation and position of the mass participation can be mixed

    • Positional parameters must be in front of the keyword arguments
    • Number + number of key parameters of the total number of positional parameters = parameter
    • A parameter can not pass many times

5.2.2.4 default parameters: You can not pass passed

  • Basic form

    def func(a,b = 9):          #b就是默认参数,默认值为9
    #func函数接受两个参数,调用函数进行传值时,默认参数可传可不传,不传则使用默认值,传则使用传的值
        print(a,b)
    
    func(123)                   #a = 123,b使用默认值,即b = 9
    func(11,22)                 #a = 11,b = 22
  • For the default value, if it is a variable type (variable type caution for the default value of the function)

    # 如果要想给value设置默认是空列表
    
    # 不推荐(坑)
    def func(data,value=[]): 
        pass 
    
    # 推荐
    def func(data,value=None):
        if not value:
            value = []
  • Interview questions

    def func(a,b=[]):
        b.append(a)
        return b
    
    l1 = func(1)
    l2 = func(2,[11,22])
    l3 = func(3)
    
    # [1,3]   [11,22,2]   [1,3]
    print(l1,l2,l3)
    

5.2.2.5 universal parameters (* args / ** kwargs)

  • *args

    • Receiving position can be any number of arguments, and the conversion parameter tuple (note argument and there is no distinction *)
    • Use only the location of mass participation
    • Basic form
    def func(*args):
        print(args)
    
    func(1,2)                #args = (1,2)
    func((11,22,33))         #args = ((11,22,33),)    
    func(*(11,22,33))        #args = (11,22,33)       循环元组里的元素,加入到元组中
    func(*[11,22,33,44])     #args = (11,22,33,44)    循环列表里的元素,加入到元组中
    #注意实参里有*和没有的区别
    
    #特殊情况:
    def func(a,*args,b):     #a只能使用位置参数,b只能使用关键字参数
        print(a,args,b)
    
    func(1,2,3,4,b = 5)      #a = 1,args = (2,3,4),b = 5  
    
  • ** kwargs

    • Keywords can accept any number of arguments and parameters into a dictionary (** Note arguments and there is no difference of)
    • Use only keywords pass parameters
    • Basic form
    def func(**kwargs):
        print(kwargs)
    
    func(k1 = 1,k2 = 'alex')          #kwargs = {'k1':1,'k2':'alex'}
    func(**{'k1':'v1','k2':'v2'})     #kwargs = {'k1':'v1','k2':'v2'}    
    #注意实参里有**和没有的区别  
    
  • Integrated use (used with * args and ** kwargs)

def func(*args,**kwargs):
    print(args,kwargs)
    
func(1,2,3,4,k1 = 1,k2 = 2)              #args = (1,2,3,4),kwargs = {'k1':1,'k2':2}
func(*[1,2,3],**{'k1':'v1','k2':'v2'})   #args = (1,2,3),kwargs = {'k1':'v1','k2':'v2'} 
  1. Key parameters related

    • Defined Functions

      #情况一:
      def func(a,b):
          pass
      
      #情况二:
      def func(a,b = None):
          pass
      
      #情况三:
      def func(*args,**kwargs):
          pass
      
    • Call the function: positional parameters> keyword arguments

  2. Exercises

# 1. 请写一个函数,函数计算列表 info = [11,22,33,44,55] 中所有元素的和。
def get_sum():
    info = [11,22,33,44,55]
    data = 0
    for item in info:
        data += item
    print(data)

get_sum()

# 2. 请写一个函数,函数计算列表中所有元素的和。
def get_list_sum(a1):
    data = 0
    for item in a1:
        data += item
    print(data)
    
get_list_sum([11,22,33])
get_list_sum([99,77,66])
v1 = [8712,123,123]
get_list_sum(v1)

# 3. 请写一个函数,函数将两个列表拼接起来。
def join_list(a1,a2):
    result = []
    result.extend(a1)
    result.extend(a2)
    print(result)
    
join_list([11,22,33],[55,66,77]

# 4. 计算一个列表的长度
def my_len(arg):
    count = 0
    for item in arg:
          count += 1
    print(count)

v = [11,22,33]
my_len(v)
len(v)

# 5. 发邮件的示例        
def send_email(role,to):
    template = "要给%s%s发送邮件" %(role,to,)
    print(template)
 
user_input = input('请输入角色:')
if user_input == '管理员':
    send_email('管理员','[email protected]')
elif user_input == '业务员':
    send_email('业务员','[email protected]')
elif user_input == '老板':
    send_email('老板','[email protected]')

5.2.3 return value (return)

  1. effect
    • return value
    • Terminate execution of the function
  2. Basic form
def func(arg):
    代码             #函数内容
    return 9         #返回值为9,默认:return None

val = func('ads')    #设置一个变量接收返回值
print(val) #9
#特殊情况:
def func():
    return 2,3,'alex'     #返回是一个元组

val = func()
print(val)                #(2,3,'alex')
  1. The return value related focus
    • Function does not return value, default return: None
    • Execution of internal functions in the event of the termination of return
    • return can return any type
# 练习题:

# 1. 写函数,计算一个列表中有多少个数字,打印: 列表中有%s个数字。
#    提示:type('x') == int 判断是否是数字。
# 方式一:
def get_list_counter1(data_list):
    count = 0
    for item in data_list:
        if type(item) == int:
            count += 1
    msg = "列表中有%s个数字" %(count,)
    print(msg)
    
get_list_counter1([1,22,3,'alex',8])

# 方式二:
def get_list_counter2(data_list):
    count = 0
    for item in data_list:
        if type(item) == int:
            count += 1
    return count
    
v = get_list_counter1([1,22,3,'alex',8])
msg = "列表中有%s个数字" %(v,)
print(msg)

# 2. 写函数,计算一个列表中偶数索引位置的数据构造成另外一个列表,并返回。
# 方式一:
def get_data_list1(arg):
    v = arg[::2]
    return v

data = get_data_list1([11,22,33,44,55,66])

# 方式二:
def get_data_list2(arg):
    v = []
    for i in range(0,len(arg)):
        if i % 2 == 0:
            v.append(arg[i])
    return v

data = get_data_list2([11,22,33,44,55,66])

# 3. 读取文件,将文件的内容构造成指定格式的数据,并返回。
"""
a.log文件
    alex|123|18
    eric|uiuf|19
    ...
目标结构:
a.  ["alex|123|18","eric|uiuf|19"] 并返回。
b. [['alex','123','18'],['eric','uiuf','19']]
c. [
    {'name':'alex','pwd':'123','age':'18'},
    {'name':'eric','pwd':'uiuf','age':'19'},
 ]
"""
def a():
    info = []
    with open('a.log',mode='r',encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            info.append(line)
    return info

def b():
    info = []
    with open('a.log',mode='r',encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            v = line.split('|')
            info.append(v)
    return info

def c():
    info = []
    with open('a.log',mode='r',encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            list = line.split('|')
            v = {}
            v['name'] = list[0]
            v['pwd'] = list[1]
            v['age'] = list[2]
            info.append(v)
    return info

date1 = a()
date2 = b()
date3 = c()
print(date1,date2,date3)
  1. The method of data type has no return value

    • No return value

      #示例:
      v = [11,22,33]
      v.append(99) 
      
    • Just Returns:

      #示例一:
      v = "alex"
      result = v.split('l')
      
      #示例二:
      v = {'k1':'v2'}
      result1 = v.get('k1')
      result2 = v.keys()
      
    • There + returns modified data

      #示例:
      v = [11,22,33]
      result = v.pop()          # 将被删除的数据赋值给result
      
    • Common to remember the

      • str
        • strip, returns the string
        • split, Back to list
        • replace, return the string
        • join, returns the string
      • list
        • append, no
        • insert, no
        • pop, returning data to be deleted
        • remove, no
        • find / index, returns the index of the position data
      • dict
        • get, the return value of the index key
        • keys, return all the keys dictionary
        • values, all the values ​​returned dictionary
        • items, return all the keys to the dictionary

5.2.4 summary

  1. The basic structure of a function:
#情况一
def f1():
    函数内容
f1()

#情况二
def f2(a):
    函数内容    
f2(1)

#情况三
def f3():
    函数内容
    return 
v1 = f3()

#情况四
def f4(a1,a2):
    函数内容
    return a1+a2
v2 = f4(1,7)
  1. Whether the data inside the function will be confused?
    • Internal chaos will not function executes each other
    • + Internal elements are not finished by other people using the => Destruction

5.3 Advanced Function Small

5.3.1 The function name can be used as a variable

#示例一:
def func():
    print(123)
    
func_list = [func, func, func]
# func_list[0]()
# func_list[1]()
# func_list[2]()
for item in func_list:
    v = item()
    print(v)
    
#示例二:
def func():
    print(123)
def bar():
    print(666)

info = {'k1': func, 'k2': bar}
info['k1']()
info['k2']()

#注意区别:
def func():
    return 123

func_list1 = [func,func,func]
func_list2 = [func(),func(),func()]
print(func_list1)
print(func_list2)

5.3.2 Functions can be passed as parameters

#示例:
def func(arg):
    v1 = arg()
    print(v1)    
def show():
    print(666)
    
result = func(show)
print(result)
#面试题:多个函数的调用
def func():
    print('话费查询')
def bar():
    print('语音沟通')
def base():
    print('业务办理')
def show():
    print('流量查询')
def test():
    print('人工服务')

info = {
    'f1': func,
    'f2': bar,
    'f3':base,
    'f4':show,
    'f5':test
}
choice = input('请选择要选择功能:')
function_name = info.get(choice)
if function_name:
    function_name()
else:
    print('输入错误')

5.3.3 anonymous function: lambda expression

  1. Role: for the expression of a simple function

  2. Basic form:

    #三元运算,为了解决简单的if else的情况
    if 1 == 1:
        a = 123
    else:
        a = 456
    #用三元运算表示:
    a =  123  if 1 == 1 else 456
    
    #lambda表达式,为了解决简单函数的情况
    def func(a1,a2):
        return a1 + a2 
    #用lambda表达式表示:
    func = lambda a1,a2: a1+a2          #隐含了return
    
  3. Key:

    • lambda expression can only be represented by a line function
    • When expressed as a function of lambda expressions, can not set a new variable, it can only be used as a variable parameter
    • All methods return a list of all methods basically None, string basically return the new value
  4. Exercises

    # 练习题1
    USER_LIST = []
    def func0(x):
        v = USER_LIST.append(x)
        return v 
    result = func0('alex')
    print(result)              #None
    
    # 练习题2
    def func0(x):
        v = x.strip()
        return v 
    result = func0(' alex ')
    print(result)               #'alex'
    
    # 练习题3
    USER_LIST = []
    func1 = lambda x: USER_LIST.append(x)
    v1 = func1('alex')
    print(v1)                    #None
    print(USER_LIST)             #['alex']
    
    # 练习题4
    func1 = lambda x: x.split('l')
    v1 = func1('alex')
    print(v1)                    #['a','ex']
    
    # 练习题5
    func_list = [lambda x:x.strip(), lambda y:y+199,lambda x,y:x+y]
    v1 = func_list[0]('alex ')
    print(v1)                    #'alex'
    v2 = func_list[1](100)
    print(v2)                    #299
    v3 = func_list[2](1,2)
    print(v3)                    #3
    

5.4 Functions senior

5.4.1 the return value of the function can do

#示例:
def func():
    print(123)
def bar():
    return func

v = bar()
v()

5.4.2 Closures

  1. Concept: function creates an area and maintain their own data, to facilitate the execution after call
  2. Scenario:
    • Decorator
    • SQLAlchemy source
#示例:
name = 'oldboy'
def bar(name):
    def inner():
        print(name)
    return inner
v1 = bar('alex') # { name=alex, inner }  # 闭包,为函数创建一块区域(内部变量供自己使用),为他以后执行提供数据。
v2 = bar('eric') # { name=eric, inner }
v1()
v2()

#区分:
# 不是闭包
def func1(name):
    def inner():
        return 123
    return inner 

# 是闭包:封装值 + 内层函数需要使用。
def func2(name):
    def inner():
        print(name)
        return 123
    return inner 
#练习题:
#第一题
name = 'alex'
def base():
    print(name)
def func():
    name = 'eric'
    base()
func() 
    
# 第二题
name = 'alex'
def func():
    name = 'eric'
    def base():
        print(name)
    base()
func()

# 第三题
name = 'alex'
def func():
    name = 'eric'
    def base():
        print(name)
    return base 
base = func()
base()

#注意:函数在何时被谁创建?
#示例:
info = []
def func():
    print(item)   
for item in range(10):
    info.append(func)

info[0]()


#面试题
info = []
def func(i):
    def inner():
        print(i)
    return inner
for item in range(10):
    info.append(func(item))

info[0]()
info[1]()
info[4]()

5.4.3 Higher order functions

  1. The function passed as a parameter
  2. To function as a return value
  3. Note: The function assignment

5.5 Built-in functions

Functions are divided into defined functions and built-in functions

python built-in functions Category:

5.5.1 cast

  • int() / str() / bool() / list() / tuple() / dict() / set()

5.5.2 Input Output

  • input() / print()

5.5.3 mathematical correlation

  • abs (): absolute value calculating

  • sum (): sum

  • float (): is converted to floating point (decimal)

    v = 55
    v1 = float(55)
    print(v1)        #55.0
    
    • Supplementary: int (55.5) # leaving only the integer: 55
  • max (): find the maximum value

  • min (): minimum is found

  • divmod (): Take two numbers divided by the quotient and remainder

    #示例:
    a,b = divmod(1001,5)
    print(a,b)          ##a=200,b=1
    
    
    • Note: divmod use than when paging show more

      # 练习题  请通过分页对数据进行展示
      """
      要求:
          每页显示10条数据
          让用户输入要查看的页面:页码
      """
      
      USER_LIST = []
      for i in range(1,836):
          temp = {'name':'你-%s' %i,'email':'123%[email protected]' %i }
          USER_LIST.append(temp)
      
      # 数据总条数
      total_count = len(USER_LIST)
      
      # 每页显示10条
      per_page_count= 10
      
      # 总页码数
      max_page_num,a = divmod(total_count,per_page_count)
      if a>0:
          max_page_num += 1
      
      while True:
          pager = int(input('要查看第几页:'))
          if pager < 1 or pager > max_page_num:
              print('页码不合法,必须是 1 ~ %s' %max_page_num )
          else:
              start = (pager-1) * per_page_count
              end = pager * per_page_count
              data = USER_LIST[start:end]
              for item in data:
                  print(item)
      
  • pow (): Index

    v = pow(2,3)      #相当于2**3
    print(v)         # 8
    
  • round (): to retain several decimal places, default retention integer, will be rounding

    v = round(1.127,2)       #第二个数代表保留几位小数,默认是None
    print(v)         # 1.13  四舍五入
    

5.5.4 binary conversions

  • bin (): to convert decimal to binary

  • oct (): convert from decimal to octal

  • int (): Convert other binary to decimal

    • Default: base = 10
    # 二进制转化成十进制
    v1 = '0b1101'
    result = int(v1,base=2)         #base=2说明读取的是二进制
    print(result)
    
    # 八进制转化成十进制
    v1 = '0o1101'
    result = int(v1,base=8)
    print(result)
    
    # 十六进制转化成十进制
    v1 = '0x1101'
    result = int(v1,base=16)
    print(result)
    
  • hex (): to convert from decimal to hexadecimal

#1字节等于8位
# IP: 192.168.12.79  ->  001010010 . 001010010 . 001010010 . 001010010

# 请将 ip = "192.168.12.79" 中的每个十进制数转换成二进制并通过,连接起来生成一个新的字符串。
ip = "192.168.12.79"
ip_list = ip.split('.') # ['192','168','12','79']
result = []
for item in ip_list:
    result.append(bin(int(item)))
print(','.join(result))


#面试题:
# 请将 ip = "192.168.12.79" 中的每个十进制数转换成二进制: 
#          0010100100001010010001010010001010010 -> 十进制的值。
# 3232238671
ip = '192.168.12.79'
v = ip.split('.')
info = []
for i in v:
    date = str(bin(int(i)))
    if len(date) > 10:
        date = date[-8:]
    else:
        count = 10 - len(date)
        date = date.replace('0b','0'*count)
    info.append(date)
val = "".join(info)
a = int(val,base=2)
print(a)

5.5.5 coding related

  • chr (): corresponds to the decimal number into a string of unicode encoding

  • ord (): The decimal character is found the corresponding unicode encoding

    #应用:生成随机验证码
    import random          # 导入一个模块 
    def get_random_code(length=6):
        data = []
        for i in range(length):
            v = random.randint(65,90)
            data.append(chr(v))
        return  ''.join(data)
    
    code = get_random_code()
    print(code)
    

5.5.6 Advanced built-in functions

  • map (function, iterables): executed together

    • Each element of the cycle (the second parameter), and then let each element performs the function (first parameter) to save the results of each function performed to the new list, and returns
    #示例:
    v1 = [11,22,33,44]
    result = map(lambda x:x+100,v1)
    print(list(result)) 
    
  • filter (function, iterable): screening

    #示例:
    v1 = [11,22,33,'asd',44,'xf']
    
    def func(x):
        if type(x) == int:
            return True
        return False
    result = filter(func,v1) 
    print(list(result))
    
    # 用lambda表达式:
    result = filter(lambda x: True if type(x) == int else False ,v1)
    print(list(result))
    # 相当于:
    result = filter(lambda x: type(x) == int ,v1)
    print(list(result))
    
  • map / filter (python2 and python3 difference nine)

    • python2: Returns a list directly create value, by index value
    • python3: returns an iterator, does not create value directly, through the cycle, while circulating create
  • reduce (function iterables): Results obtained

    import functools
    v1 = ['wo','hao','e']
    def func(x,y):
        return x+y
    result = functools.reduce(func,v1) 
    print(result)
    
    # 用lambda表达式:
    result = functools.reduce(lambda x,y:x+y,v1)
    print(result)
    

5.5.7 or related

  • type (): View data types

    class Foo:
        pass
    
    obj = Foo()
    if type(obj) == Foo:
        print('obj是Foo类的对象')
    
  • issubclass (Class A, or base class): before the judgment of whether a class is a subclass of the base class or

    • The result is a Boolean type, is a -> True, no -> False
    class Base:
        pass
    
    class Base1(Base):
        pass
    
    class Foo(Base1):
        pass
    
    class Bar:
        pass
    
    print(issubclass(Bar,Base))
    print(issubclass(Foo,Base))
    
  • the isinstance (object class or a base class): determining whether an object is an instance of a class or a base class (object)

    • The result is a Boolean type, is a -> True, no -> False
    • Note: to determine whether an object is an instance (object) of a class, must use type, do not use isinstance
    class Base(object):
        pass
    
    class Foo(Base):
        pass
    
    obj = Foo()
    print(isinstance(obj,Foo))  # 判断obj是否是Foo类或其基类的实例(对象)
    print(isinstance(obj,Base)) # 判断obj是否是Foo类或其基类的实例(对象)
    
  • super () method name (): According to the inheritance class self object belongs, in accordance with the order to find ways and execution (find the first date)

    class Base(object):
        def func(self):
            super().func()  # 根据self对象所属类的继承关系,按照顺序挨个找func方法并执行(找到第一个为止)
            print('base.func')
    
    class Bar(object):
        def func(self):
            print('bar.func')
    
    class Foo(Base,Bar): # Foo -> Base -> Bar
        pass
    
    obj = Foo()
    obj.func()
    

5.5.8 Other

  • len (): calculated length
  • open (): open the file
  • range()
  • id (): View the memory address

5.7 Scope

5.7.1 Classification

  • Global scope: the python, the equivalent of a py file

    • Variable global scope called a global variable
    • Global variables must be all uppercase
  • Local scope: in python, a function equivalent to

    • Variable local scope called local variables
    • Local variables are in lower case
    USER_LIST = [11,22,3]         #全局变量
    def func():
        name = 'asdf'             #局部变量
        USER_LIST.append(12)
        USER_LIST.append(name)
    func()
    print(USER_LIST)
    

5.7.2 Recursion

  • Function calls itself. (low efficiency)

    def func():
        print(1)
        func()
    
    func()
    
    # 递归的返回值
    def func(a):
        if a == 5:
            return 100000
        result = func(a+1) + 10
    v = func(1)
    
    name = 'alex'
    def func():
        def inner():
            print(name)
         return inner
    v =func()
    

5.7.3 summary

  • In python, a function is a scope

  • Find data scope rules:

    • Priority find data in its own scope in
    • I did not go to 'parent' in the find, no go 'parent' of the 'parent' in looking until to find global scope
    • Finally, if there is no global scope, it will error
    • Note When looking for: what value the role of the parent domain in the end is
    #示例一:
    x = 10
    def func():
        x = 9
        print(x)           
        def x1():
            x = 8
            print(x)
    func()               # 9
    
    #示例二:
    x = 10
    def func():
        x = 9
        print(x)
        def x1():
            x = 8
            print(x)
        x1()
    func()               # 9   8
    
    #示例三:
    x = 10
    def func():
        x = 9
        print(x)
        def x1():
            x = 8
            print(x)
        print(x)
        x1()
    func()               # 9   9   8   
    
    #示例四:
    x = 10
    def func():
        x = 9
        print(x)
        def x1():
            x = 8
            print(x)
        x1()
        print(x)
    func()               # 9   8   9 
    
    #示例五:
    x = 10
    def func():
        x = 9
        print(x)
        def x1():
            print(x)
        x1()
        print(x)
    func()               # 9   9   9
    
    #示例六:
    x = 10
    def func():
        x = 8
        print(x)
        def x1():
            print(x)
        x = 9
        x1()
        x = 10
        print(x)
    func()               # 8   9   10
    
    #示例七:
    x = 10
    def func():
        x = 8
        print(x)
        def x1():
            print(x)
        x1()
        x = 9
        x1()
        x = 10
        print(x)
    func()               # 8   8   9   10
    
  • For the child scope:

    • Only to find the value of the 'parent' of default can not back to 'parent' variable assignment

    • If you have to re-assignment to a variable, using global / nonlocal mandatory assignment

      • global: directly to global variables, and then re-assignment, the other does not change
      • nonlocal: found only 'parent' of variables, re-assignment, the other does not change
      • Recommendation: generally do not use, so as to avoid confusing code
      #global示例:
      name = 'oldboy'
      def func():
          name = 'alex'
          def inner():
              global name      #直接找到全局的name
              name = 'abc'     #再进行重新赋值
          inner()
          print(name)          #'alex'
      func()
      print(name)              #'abc'
      
      #nonlocal示例:
      name = "oldboy"
      def func():
          name = 'alex'
          def inner():
              nonlocal name    #找到上一级的name
              name = 'abc'     #再进行重新赋值
          inner()
          print(name)          #'abc'
      func()
      print(name)              #"oldboy"
      

5.8 derivations

5.8.1 List comprehensions

# 目的:方便的生成一个列表
# 格式:
v1 = [i for i in 可迭代对象 ]
v2 = [i for i in 可迭代对象 if 条件 ]      #条件为true才进行append
# 示例:
v1 = [ i for i in 'alex' ]  
v2 = [i+100 for i in range(10)]
v3 = [99 if i>5 else 66  for i in range(10)]

def func():
    return 100
v4 = [func for i in range(10)]

v5 = [lambda : 100 for i in range(10)]
result = v5[9]()

v6 = [lambda :i for i in range(10)]
result = v6[5]()

# 新浪微博面试题
v7 = [lambda x:x*i for i in range(10)] 
# 1.请问 v7 是什么?
# 2.请问 v7[0](2) 的结果是什么?

# 面试题
def num():
    return [lambda x:i*x for i in range(4)]
# num() -> [函数,函数,函数,函数]
print([ m(2) for m in num() ]) # [6,6,6,6]

5.8.2 set derivations

# 目的:方便的生成一个集合
# 格式:
v1 = { i for i in 'alex' }

5.8.3 Dictionary derivations

# 目的:方便的生成一个字典
# 格式:
v1 = { 'k'+str(i):i for i in range(10)}

5.8.4 Generator derivations

# 列表推导式,立即循环创建所有元素
"""
def func():
    result = []
    for i in range(10):
        result.append(i)
    return result
v1 = func()
"""
v1 = [i for i in range(10)]
print(v1)

# 生成器推导式,创建了一个生成器,内部循环为执行
"""
def func():
    for i in range(10):
        yield i
v2 = func()
"""
v2 = (i for i in range(10))
for item in v2:
    print(item)

# 面试题:请比较 [i for i in range(10)] 和 (i for i in range(10)) 的区别?

5.9 decorator

5.8.1 Objective

  • Without changing the original function of the internal code, before and after the function is executed automatically perform a certain function

5.8.2 application scenarios

  • When you want to function as extensions, you can choose to use decorator

5.8.3 Basic decorator

  1. The basic format:

    def func(arg):
        def inner():
            v = arg()
            return v 
        return inner 
    
    # 重点:
    # 第一步:执行func函数并将下面的函数参数传递,相当于:func(index)
    # 第二步:将func的返回值重新赋值给下面的函数名。 index = func(index)
    @func 
    def index():
        print(123)
        return 666
    
    print(index)
    
  2. to sum up

    • Write format:
    def 外层函数(参数):
        def 内层函数(*args,**kwargs)
         return 参数(*args,**kwargs)
        return 内层函数
    
    • Application form:
    @外层函数
    def index():             #要装饰的函数
        pass
    
    index()
    
    # 装饰器的编写
    def x(func):
        def y():
            # 前
            ret = func()
            # 后
            return ret 
         return y 
    
    # 装饰器的应用
    @x
    def index():
        return 10
    
    # 执行函数,自动触发装饰器了
    v = index()
    print(v)
    
  3. Example:

    def func(arg):
        def inner():
            print('before')
            v = arg()
            print('after')
            return v 
        return inner 
    
    def index():
        print('123')
        return '666'
    
    # 示例一
    v1 = index() # 执行index函数,打印123并返回666赋值给v1.
    
    # 示例二
    v2 = func(index) # v2是inner函数,arg=index函数
    index = 666 
    v3 = v2()
    
    # 示例三
    v4 = func(index)
    index = v4  # index ==> inner 
    index()
    
    # 示例四
    index = func(index)
    index()
    

5.8.4 decorator with parameters

  1. Application scenarios: flask frame / django cache / write decorator realize the decorated function to execute N times

    # 第一步:执行 ret = xxx(index)
    # 第二步:将返回值赋值给 index = ret 
    @xxx
    def index():
        pass
    
    # 第一步:执行 v1 = uuu(9)
    # 第二步:ret = v1(index)
    # 第三步:index = ret 
    @uuu(9)
    def index():
        pass
    
  2. the difference:

    # 普通装饰器
    def wrapper(func):
        def inner(*args,**kwargs):
            data = func(*args,**kwargs) # 执行原函数并获取返回值
            return data
        return inner 
    
    @wrapper
    def index():
        pass
    
    # 带参数装饰器 
    def x(counter):
        def wrapper(func):
            def inner(*args,**kwargs):
                data = func(*args,**kwargs) # 执行原函数并获取返回值
                return data
            return inner 
     return wrapper 
    
    @x(9)
    def index():
        pass
    
  3. Exercises

    # 习题一:
    # 写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,把每次结果添加到列表中,最终返回列表。
    def xxx(counter):
        def wrapper(func):
            def inner(*args,**kwargs):
                v = []
                for i in range(counter):
                    data = func(*args,**kwargs) # 执行原函数并获取返回值
                    v.append(data)
                return v
            return inner
        return wrapper
    
    @xxx(5)
    def index():
        return 8
    v = index()
    print(v)
    
    # 习题二:
    # 写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,并返回最后一次执行的结果【面试题】
    def xxx(counter):
        def wrapper(func):
            def inner(*args,**kwargs):
                for i in range(counter):
                    data = func(*args,**kwargs) # 执行原函数并获取返回值
                return data
            return inner
        return wrapper
    
    @xxx(5)
    def index():
        return 8
    v = index()
    print(v)
    
    # 习题三:
    # 写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,并返回执行结果中最大的值。
    def xxx(counter):
        def wrapper(func):
            def inner(*args,**kwargs):
                value = 0
                for i in range(counter):
                    data = func(*args,**kwargs) # 执行原函数并获取返回值
                    if data > value:
                        value = data 
                return value
            return inner
        return wrapper
    
    @xxx(5)
    def index():
        return 8
    v = index()
    print(v)
    

5.10 iterator

5.10.1 Basics

  1. Uses: for certain objects (str / list / tuple / Object dict / set class created - iterables) acquired by one of the elements

  2. Appearance: a __next__method invocation and each iteration can obtain the object element (acquired one by one from front to back)

  3. Example:

    • List converted into iterator:
      • traveling v1 = ([11,22,33,44])
      • v1 = [11,22,33,44].__iter__()
    • Iterator want to get each value: Repeated calls val = v1.__next__()
    v1 = [11,22,33,44]
    
    # 列表转换成迭代器
    v2 = iter(v1)
    
    # 迭代器获取每个值
    result1 = v2.__next__()
    print(result1)
    result2 = v2.__next__()
    print(result2)
    result3 = v2.__next__()
    print(result3)
    result4 = v2.__next__()
    print(result4)
    
    result5 = v2.__next__()
    print(result5)    # 报错:Stoplteration    表示已经迭代结束
    
  4. for loop: use of iterators

    v1 = [11,22,33,44]
    
    # 1.内部会将v1转换成迭代器
    # 2.内部反复执行 迭代器.__next__()
    # 3.取完不报错
    for item in v1:
        print(item)
    

5.10.2 iterables

  1. Appearance: for loop can be an object can be called iterables

  2. How to make an object become iterable?

    • Implemented in a class __iter__method and returns an iterator (Builder)
    # 示例一:
    class Foo:
        def __iter__(self):
            return iter([1,2,3,4])
    
    obj = Foo()
    
    # 示例二:
    class Foo:
        def __iter__(self):
            yield 1
            yield 2
            yield 3
    
    obj = Foo()
    
  3. Note: As long as can be for the cycle, is to see his internal __iter__method

5.11 Generator

5.11.1 Basics

  1. It can be understood as: variogram, special iterator special iterables

  2. Generator effect:

    • Generating data
    • Iteration
  3. Example:

    # 生成器函数(内部是否包含yield)
    def func():
        print('F1')
        yield 1
        print('F2')
        yield 2
        print('F3')
        yield 100
        print('F4')
    # 函数内部代码不会执行,返回一个 生成器对象 。
    v1 = func()
    # 生成器是可以被for循环,一旦开始循环那么函数内部代码就会开始执行。
    for item in v1:
        print(item)
    

5.11.2 Keyword

  1. yield

    • Usage: if the function is a function generator
  2. yield from

    • Purpose: jumps from the other current generator function generator function, and then ends the execution back to the original function continues to execute the code below
    def base():
        yield 88
        yield 99
    
    def func():
        yield 1
        yield 2
        yield from base()   # 跳到base函数
        yield 3
    
    result = func()
    for item in result:
        print(item)       # 1   2   88   99   3
    

5.11.3 summary

  1. Key:

    • If the yield function is present, then the function is a function generator
    • Call the generator function returns a generator
    • Only when the generator for circulation, the code generator will perform an internal function, each loop will get the value of the return yield
  2. Suggest:

    • Generator function in general do not have a return

    • If desired function generator terminates the loop, the return can be used

      def func():
          count = 1
          while True:
              yield count
              count += 1
              if count == 100:
                  return
      val = func()
      for item in val:
          print(item)
      
  3. Generator Example: Reading the contents of the documents

    def func():
        #  分批去读取文件中的内容,将文件的内容返回给调用者。
        cursor = 0
        while True:
            f = open('db', 'r', encoding='utf-8')    # 通过网络连接上redis
            # 代指  redis[0:10]
            f.seek(cursor)
            data_list =[]
            for i in range(10):
                line = f.readline()
                if not line:
                    return
                data_list.append(line)
            cursor = f.tell()
            f.close()  # 关闭与redis的连接
    
            for row in data_list:
                yield row
    
    for item in func():
        print(item)
    

Guess you like

Origin www.cnblogs.com/hanfe1/p/11511116.html