精华内容
下载资源
问答
  • 这里有一个点,localhost 默认 ip 是 172.0.0.1,这是一个回路段,也叫换回接口。也就是不会发往服务器,是直接在本地打开的。 <h4>3. 路由器缓存、ISP 缓存 如果浏览器和系统缓存都没有&#...
  • 制作思路:利用太阳能管理模块搭配15块光伏板,作为一个独立的电源,为整个时钟供电,这样做的好处是脱离额外电线的束缚,不影响窗户的正常推拉使用。时钟根据电量计测得的电量多少,分别对应3个模式。模式1(电量>...
  • ...事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。 可以用Python的程序来计算出这个值,代码如下所示。 # -*- coding: utf-8 -*- """ 输入M和N计算C(M,N) C...
    • 学习链接:https://github.com/jackfrued/Python-100-Days

    • 请说出下面的方程有多少组正整数解。
      在这里插入图片描述
      事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。
      在这里插入图片描述
      可以用Python的程序来计算出这个值,代码如下所示。

        # -*- coding: utf-8 -*-
        """
        输入M和N计算C(M,N)
        Created on Tue Jul 30 16:28:37 2019
        
        @author: fengzi
        """
        m = int(input("m = "))
        n = int(input("n = "))
        fm = 1
        for num in range(1, m+1):
            fm *= num
        fn = 1
        for num in range(1, n + 1):
            fn *= num
        fmn = 1
        for num in range(1,m - n + 71):
            fmn *= num
        print(fm // fn // fmn)
    

    在这里插入图片描述

    • 定义函数
      1、在Python中可以使用def关键字来定义函数
      2、函数执行完成后我们可以通过return关键字来返回一个值
        # -*- coding: utf-8 -*-
        """
        函数 阶乘
        
        Created on Tue Jul 30 23:05:09 2019
        
        @author: fengzi
        """
        
        def factorial(num):
            """
            求阶乘
            param num:非负整数
            return:num的阶乘
        
        """
            result = 1
            for n in range(1, num + 1):
                result *= n
            return result
        
        m = int(input("m = "))
        n = int(input("n = "))
        # 当需要计算阶乘的时候不用再写循环求阶乘而是直接调用已经定义好的函数
        print(factorial(m) // factorial(n) // factorial(m - n))
    
    • 说明: Python的math模块中其实已经有一个factorial函数了,事实上要计算阶乘可以直接使用这个现成的函数而不用自己定义。下面例子中的某些函数其实Python中也是内置了,我们这里是为了讲解函数的定义和使用才把它们又实现了一遍,实际开发中不建议做这种低级的重复性的工作。

    • 函数的参数

    # -*- coding: utf-8 -*-
    """
    Created on Sat Aug  3 17:48:33 2019
    
    @author: fengzi
    """
    
    from random import randint
    
    def roll_dice(n = 2):
        """
        摇色子
        param n :色子的个数
        returm : n颗色子点数之和
        """
        
        total = 0
        for _ in range(n):
            total += randint(1, 6)
        return total
    
    def add(a = 0, b = 0, c = 0):
        return a + b + c
    #如果没有指定参数那么使用默认值摇两颗色子
    print(roll_dice())
    #摇三颗色子
    print(roll_dice(3))
    print(add())
    print(add(1))
    print(add(1, 2))
    print(add(1, 2, 3))
    
    #传递参数时可以不按照设定的顺序进行传递
    print(add(c = 50, a = 100, b = 200))
    

    在这里插入图片描述

    上面的add函数还有更好的实现方案,因为我们可能会对0个或多个参数进行加法运算,而具体有多少个参数是由调用者来决定,我们作为函数的设计者对这一点是一无所知的,因此在不确定参数个数的时候,我们可以使用可变参数,代码如下所示。

    # -*- coding: utf-8 -*-
    """
    Created on Mon Aug  5 11:22:15 2019
    
    @author: fengzi
    """
    
    # 在参数名前面的*表示args是一个可变参数
    # 即在调用add函数时可以传入0个或多个参数
    def add(*args):
        tatal = 0
        for val in args:
            tatal += val
        return tatal
    print(add())
    print(add(1))
    print(add(1, 2))
    print(add(1, 2, 3))
    print(add(1, 2, 3, 7, 9))
    

    在这里插入图片描述

    用模块管理函数

    • 同一个.py文件中定义了两个同名函数,由于Python没有函数重载的概念,那么后面的定义会覆盖之前的定义,也就意味着两个函数同名函数实际上只有一个是存在的。
    def foo():
        print("hello,world!")
        
    def foo():
        print("goodbye,world!")
    
    foo()
    

    在这里插入图片描述

    • 调用模块函数
    # -*- coding: utf-8 -*-
    """
    Created on Mon Aug  5 11:51:43 2019
    
    @author: fengzi
    """
    
    from module1 import foo
    # 输出hello, world!
    foo()
    
    from module2 import foo
    # 输出goodbye, world!
    foo()
    

    在这里插入图片描述

    • 也可以按照如下所示的方式来区分到底要使用哪一个foo函数。
    import module1 as m1
    import module2 as m2
    
    m1.foo()
    m2.foo()
    

    在这里插入图片描述

    • 但是如果将代码写成了下面的样子,那么程序中调用的是最后导入的那个foo,因为后导入的foo覆盖了之前导入的foo。
    from module1 import foo
    from module2 import foo
    
    # 输出goodbye, world!
    foo()
    
    from module2 import foo
    from module1 import foo
    
    # 输出hello, world!
    foo()
    
    • 需要说明的是,如果我们导入的模块除了定义函数之外还中有可以执行代码,那么Python解释器在导入这个模块时就会执行这些代码,事实上我们可能并不希望如此,因此如果我们在模块中编写了执行代码,最好是将这些执行代码放入如下所示的条件中,这样的话除非直接运行该模块,if条件下的这些代码是不会执行的,因为只有直接执行的模块的名字才是“main”。
    # -*- coding: utf-8 -*-
    """
    Created on Mon Aug  5 14:52:35 2019
    
    @author: fengzi
    """
    
    def foo():
        pass
    
    def bar():
        pass
    
    # __name__是Python中一个隐含的变量它代表了模块的名字
    # 只有被Python解释器直接执行的模块的名字才是__main__
    if __name__ == "__main__":
        print("call foo()")
        foo()
        print("call bar()")
        bar()
    

    在这里插入图片描述

    import module3
    
    # 导入module3时 不会执行模块中if条件成立时的代码 因为模块的名字是module3而不是__main__
    

    练习

    练习1:实现计算求最大公约数和最小公倍数的函数。

    # -*- coding: utf-8 -*-
    """
    Created on Mon Aug  5 14:58:56 2019
    
    @author: fengzi
    """
    
    def gcd(x, y):
        (x, y) = (y, x) if x > y else (x, y)
        for factor in range(x, 0, -1):
            if x % factor == 0 and y % factor == 0:
                return factor
            
            
    def lcm(x, y):
        return x * y // gcd(x, y)
    

    练习2:实现判断一个数是不是回文数的函数。

    # -*- coding: utf-8 -*-
    """
    Created on Mon Aug  5 15:18:53 2019
    
    @author: fengzi
    """
    
    def is_palindrome(num):
        temp = num
        total = 0
        while temp > 0:
            total = total * 10 + temp % 10
            temp //= 10
        return total == num 
    

    练习3:实现判断一个数是不是素数的函数。

    # -*- coding: utf-8 -*-
    """
    Created on Mon Aug  5 15:20:56 2019
    
    @author: fengzi
    """
    
    def is_prime(num):
        for factor in range(2, num):
            if num % factor == 0:
                return False
        return True if num != 1 else False
    

    练习4:写一个程序判断输入的正整数是不是回文素数。

    # -*- coding: utf-8 -*-
    """
    Created on Mon Aug  5 15:22:11 2019
    
    @author: fengzi
    """
    
    from module5 import is_palindrome 
    from module4 import is_prime 
    
    if __name__ == '__main__':
        num = int(input("请输入正整数:"))
        if is_palindrome(num) and is_prime(num):
            print("%d是回文素数" % num)
        else:
            print("%d不是回文素数" % num)
    

    在这里插入图片描述

    展开全文
  • es6新特性之模块化开发

    千次阅读 2020-03-27 22:07:45
    以往我们是直接引入一些外部的js文件,有多少引多少,这样会造成一个js文件夹很多js文件,而且要一个一个的引入,影响浏览速度 在es6中支持了模块化开发,即你只需要引入一个入口的js文件,并不需要输入script标签...

    以往我们是直接引入一些外部的js文件,有多少引多少,这样会造成一个js文件夹很多js文件,而且要一个一个的引入,影响浏览速度
    在es6中支持了模块化开发,即你只需要引入一个入口的js文件,并不需要输入script标签引入
    这一点有点像python
    但是现在的浏览器是不支持es6的模块化的,我们能需要通过webpack这个工具进行打包已实现模块化开发

    模块化基本语法

    导出

    • export name导出name;name可以是函数,类,变量,数字,对象…
    • export default name默认导出
    • export * from '...js'引入另一个js并将其导出
    • export {a,v,c,d} from '...js'只引入部分内容并导出
    • export {default} from '...js'引入另一个文件的default并导出

    引入

    • import * as test from '....js' 引入全部内容
    • import {a,b,c} from '....js' 引入指定内容
    • import main from '....js'引入export default
    • let promise=import ('/path')异步引入,返回promise对象

    webpack打包

    1.下载webpack
    npm i webpack -g
    2.项目目录新键一个webpack的配置文件 webpack.config.js
    键入如下内容

    const path=require('path');
    module.exports={
        entry:'./src/index.js',//入口文件
        output:{
            path:path.resolve(__dirname,'build'),//打包后js存放路径
            filename:'bundle.js'//最后生成的打包文件
        }
    }
    

    3.测试webpack打包
    3.1新键index.js这个js文件引进外部js main.js

    //index.js
    import * as main from './main.js';//引入main.js全部内容并重命名为main
    let one = new main.Person('test',19);
    one.show();
    //main.js
    
     export class Person{
    	constructor(name,age){
    		this.name = name;
    		this.age = age;
    	}
    	show(){
    		console.log(this.name,this.age)
    	}
    }
    

    3.2命令行打包
    输入webpack
    在这里插入图片描述
    3.3新键html文件引入刚才打包的js文件 项目目录/build/bundle.js

    <script type="text/javascript" src="./build/bundle.js"></script>
    

    这样即完成基本的模块化操作

    展开全文
  • 一个字节对应8位二进制数,这也决定了他们能表达数值的范围是差异的。现在给你一些数据类型的查询,请输出其对应的字节数。 建议大家使用函数进行模块化编程,例如: int getByteofType(char t[]) { } int ...
  • 事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。 $$C_M^N =\frac{M!}{N!(M-N)!}, \text{(M=7, N=3)} $$ 可以用Python的程序来计算出这个值,代码如下...
  • 事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。 可以用Python的程序来计算出这个值,代码如下所示。 """ 输入M和N计算C(M,N) """ m = int(input('m...

    函数和模块的使用

    在讲解本章节的内容之前,我们先来研究一道数学题,请说出下面的方程有多少组正整数解。

    事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。

    可以用Python的程序来计算出这个值,代码如下所示。

    """
    输入M和N计算C(M,N)
    """
    
    m = int(input('m = '))
    n = int(input('n = '))
    fm = 1
    for num in range(1, m + 1):
        fm *= num
    fn = 1
    for num in range(1, n + 1):
        fn *= num
    fmn = 1
    for num in range(1, m - n + 1):
        fmn *= num
    print(fm // fn // fmn)
    

    函数的作用

    不知道大家是否注意到,在上面的代码中,我们做了3次求阶乘,这样的代码实际上就是重复代码。编程大师Martin Fowler先生曾经说过:“代码有很多种坏味道,重复是最坏的一种!”,要写出高质量的代码首先要解决的就是重复代码的问题。对于上面的代码来说,我们可以将计算阶乘的功能封装到一个称之为“函数”的功能模块中,在需要计算阶乘的地方,我们只需要“调用”这个“函数”就可以了。

    定义函数

    在Python中可以使用def关键字来定义函数,和变量一样每个函数也有一个响亮的名字,而且命名规则跟变量的命名规则是一致的。在函数名后面的圆括号中可以放置传递给函数的参数,这一点和数学上的函数非常相似,程序中函数的参数就相当于是数学上说的函数的自变量,而函数执行完成后我们可以通过return关键字来返回一个值,这相当于数学上说的函数的因变量。

    在了解了如何定义函数后,我们可以对上面的代码进行重构,所谓重构就是在不影响代码执行结果的前提下对代码的结构进行调整,重构之后的代码如下所示。

    def factorial(num):
        """
        求阶乘
        
        :param num: 非负整数
        :return: num的阶乘
        """
        result = 1
        for n in range(1, num + 1):
            result *= n
        return result
    
    
    m = int(input('m = '))
    n = int(input('n = '))
    # 当需要计算阶乘的时候不用再写循环求阶乘而是直接调用已经定义好的函数
    print(factorial(m) // factorial(n) // factorial(m - n))
    

    说明: Python的math模块中其实已经有一个factorial函数了,事实上要计算阶乘可以直接使用这个现成的函数而不用自己定义。下面例子中的某些函数其实Python中也是内置了,我们这里是为了讲解函数的定义和使用才把它们又实现了一遍,实际开发中不建议做这种低级的重复性的工作。

    函数的参数

    函数是绝大多数编程语言中都支持的一个代码的“构建块”,但是Python中的函数与其他语言中的函数还是有很多不太相同的地方,其中一个显著的区别就是Python对函数参数的处理。在Python中,函数的参数可以有默认值,也支持使用可变参数,所以Python并不需要像其他语言一样支持函数的重载,因为我们在定义一个函数的时候可以让它有多种不同的使用方式,下面是两个小例子。

    from random import randint
    
    
    def roll_dice(n=2):
        """
        摇色子
        
        :param n: 色子的个数
        :return: n颗色子点数之和
        """
        total = 0
        for _ in range(n):
            total += randint(1, 6)
        return total
    
    
    def add(a=0, b=0, c=0):
        return a + b + c
    
    
    # 如果没有指定参数那么使用默认值摇两颗色子
    print(roll_dice())
    # 摇三颗色子
    print(roll_dice(3))
    print(add())
    print(add(1))
    print(add(1, 2))
    print(add(1, 2, 3))
    # 传递参数时可以不按照设定的顺序进行传递
    print(add(c=50, a=100, b=200))
    

    我们给上面两个函数的参数都设定了默认值,这也就意味着如果在调用函数的时候如果没有传入对应参数的值时将使用该参数的默认值,所以在上面的代码中我们可以用各种不同的方式去调用add函数,这跟其他很多语言中函数重载的效果是一致的。

    其实上面的add函数还有更好的实现方案,因为我们可能会对0个或多个参数进行加法运算,而具体有多少个参数是由调用者来决定,我们作为函数的设计者对这一点是一无所知的,因此在不确定参数个数的时候,我们可以使用可变参数,代码如下所示。

    # 在参数名前面的*表示args是一个可变参数
    # 即在调用add函数时可以传入0个或多个参数
    def add(*args):
        total = 0
        for val in args:
            total += val
        return total
    
    
    print(add())
    print(add(1))
    print(add(1, 2))
    print(add(1, 2, 3))
    print(add(1, 3, 5, 7, 9))
    

    用模块管理函数

    对于任何一种编程语言来说,给变量、函数这样的标识符起名字都是一个让人头疼的问题,因为我们会遇到命名冲突这种尴尬的情况。最简单的场景就是在同一个.py文件中定义了两个同名函数,由于Python没有函数重载的概念,那么后面的定义会覆盖之前的定义,也就意味着两个函数同名函数实际上只有一个是存在的。

    def foo():
        print('hello, world!')
    
    
    def foo():
        print('goodbye, world!')
    
    
    # 下面的代码会输出什么呢?
    foo()
    

    当然上面的这种情况我们很容易就能避免,但是如果项目是由多人协作进行团队开发的时候,团队中可能有多个程序员都定义了名为foo的函数,那么怎么解决这种命名冲突呢?答案其实很简单,Python中每个文件就代表了一个模块(module),我们在不同的模块中可以有同名的函数,在使用函数的时候我们通过import关键字导入指定的模块就可以区分到底要使用的是哪个模块中的foo函数,代码如下所示。

    module1.py

    def foo():
        print('hello, world!')
    

    module2.py

    def foo():
        print('goodbye, world!')
    

    test.py

    from module1 import foo
    
    # 输出hello, world!
    foo()
    
    from module2 import foo
    
    # 输出goodbye, world!
    foo()
    

    也可以按照如下所示的方式来区分到底要使用哪一个foo函数。

    test.py

    import module1 as m1
    import module2 as m2
    
    m1.foo()
    m2.foo()
    

    但是如果将代码写成了下面的样子,那么程序中调用的是最后导入的那个foo,因为后导入的foo覆盖了之前导入的foo

    test.py

    from module1 import foo
    from module2 import foo
    
    # 输出goodbye, world!
    foo()
    

    test.py

    from module2 import foo
    from module1 import foo
    
    # 输出hello, world!
    foo()
    

    需要说明的是,如果我们导入的模块除了定义函数之外还中有可以执行代码,那么Python解释器在导入这个模块时就会执行这些代码,事实上我们可能并不希望如此,因此如果我们在模块中编写了执行代码,最好是将这些执行代码放入如下所示的条件中,这样的话除非直接运行该模块,if条件下的这些代码是不会执行的,因为只有直接执行的模块的名字才是“__main__”。

    module3.py

    def foo():
        pass
    
    
    def bar():
        pass
    
    
    # __name__是Python中一个隐含的变量它代表了模块的名字
    # 只有被Python解释器直接执行的模块的名字才是__main__
    if __name__ == '__main__':
        print('call foo()')
        foo()
        print('call bar()')
        bar()
    

    test.py

    import module3
    
    # 导入module3时 不会执行模块中if条件成立时的代码 因为模块的名字是module3而不是__main__
    

    练习

    练习1:实现计算求最大公约数和最小公倍数的函数。

    def gcd(x, y):
        (x, y) = (y, x) if x > y else (x, y)
        for factor in range(x, 0, -1):
            if x % factor == 0 and y % factor == 0:
                return factor
    
    
    def lcm(x, y):
        return x * y // gcd(x, y)
    

    练习2:实现判断一个数是不是回文数的函数。

    def is_palindrome(num):
        temp = num
        total = 0
        while temp > 0:
            total = total * 10 + temp % 10
            temp //= 10
        return total == num
    

    练习3:实现判断一个数是不是素数的函数。

    def is_prime(num):
        for factor in range(2, num):
            if num % factor == 0:
                return False
        return True if num != 1 else False
    

    练习4:写一个程序判断输入的正整数是不是回文素数。

    if __name__ == '__main__':
        num = int(input('请输入正整数: '))
        if is_palindrome(num) and is_prime(num):
            print('%d是回文素数' % num)
    

    通过上面的程序可以看出,当我们将代码中重复出现的和相对独立的功能抽取成函数后,我们可以组合使用这些函数来解决更为复杂的问题,这也是我们为什么要定义和使用函数的一个非常重要的原因。

    最后,我们来讨论一下Python中有关变量作用域的问题。

    def foo():
        b = 'hello'
    
        def bar():  # Python中可以在函数内部再定义函数
            c = True
            print(a)
            print(b)
            print(c)
    
        bar()
        # print(c)  # NameError: name 'c' is not defined
    
    
    if __name__ == '__main__':
        a = 100
        # print(b)  # NameError: name 'b' is not defined
        foo()
    

    上面的代码能够顺利的执行并且打印出100和“hello”,但我们注意到了,在bar函数的内部并没有定义ab两个变量,那么ab是从哪里来的。我们在上面代码的if分支中定义了一个变量a,这是一个全局变量(global variable),属于全局作用域,因为它没有定义在任何一个函数中。在上面的foo函数中我们定义了变量b,这是一个定义在函数中的局部变量(local variable),属于局部作用域,在foo函数的外部并不能访问到它;但对于foo函数内部的bar函数来说,变量b属于嵌套作用域,在bar函数中我们是可以访问到它的。bar函数中的变量c属于局部作用域,在bar函数之外是无法访问的。事实上,Python查找一个变量时会按照“局部作用域”、“嵌套作用域”、“全局作用域”和“内置作用域”的顺序进行搜索,前三者我们在上面的代码中已经看到了,所谓的“内置作用域”就是Python内置的那些隐含标识符minlen等都属于内置作用域)。

    再看看下面这段代码,我们希望通过函数调用修改全局变量a的值,但实际上下面的代码是做不到的。

    def foo():
        a = 200
        print(a)  # 200
    
    
    if __name__ == '__main__':
        a = 100
        foo()
        print(a)  # 100
    

    在调用foo函数后,我们发现a的值仍然是100,这是因为当我们在函数foo中写a = 200的时候,是重新定义了一个名字为a的局部变量,它跟全局作用域的a并不是同一个变量,因为局部作用域中有了自己的变量a,因此foo函数不再搜索全局作用域中的a。如果我们希望在foo函数中修改全局作用域中的a,代码如下所示。

    def foo():
        global a
        a = 200
        print(a)  # 200
    
    
    if __name__ == '__main__':
        a = 100
        foo()
        print(a)  # 200
    

    我们可以使用global关键字来指示foo函数中的变量a来自于全局作用域,如果全局作用域中没有a,那么下面一行的代码就会定义变量a并将其置于全局作用域。同理,如果我们希望函数内部的函数能够修改嵌套作用域中的变量,可以使用nonlocal关键字来指示变量来自于嵌套作用域,请大家自行试验。

    在实际开发中,我们应该尽量减少对全局变量的使用,因为全局变量的作用域和影响过于广泛,可能会发生意料之外的修改和使用,除此之外全局变量比局部变量拥有更长的生命周期,可能导致对象占用的内存长时间无法被垃圾回收。事实上,减少对全局变量的使用,也是降低代码之间耦合度的一个重要举措,同时也是对迪米特法则的践行。减少全局变量的使用就意味着我们应该尽量让变量的作用域在函数的内部,但是如果我们希望将一个局部变量的生命周期延长,使其在函数调用结束后依然可以访问,这时候就需要使用闭包,这个我们在后续的内容中进行讲解。

    说明: 很多人经常会将“闭包”一词和“匿名函数”混为一谈,但实际上它们是不同的概念,如果想提前了解这个概念,推荐看看维基百科或者知乎上对这个概念的讨论。

    说了那么多,其实结论很简单,从现在开始我们可以将Python代码按照下面的格式进行书写,这一点点的改进其实就是在我们理解了函数和作用域的基础上跨出的巨大的一步。

    def main():
        # Todo: Add your code here
        pass
    
    
    if __name__ == '__main__':
        main()
    
    展开全文
  • 事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。 可以用Python的程序来计算出这个值,代码如下所示。 """ 输入M和N计算C(M,N) Version: 0.1 ...

    函数和模块的使用

    在讲解本章节的内容之前,我们先来研究一道数学题,请说出下面的方程有多少组正整数解。

    $$x_1 + x_2 + x_3 + x_4 = 8$$

    事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。

    $$C_M^N =\frac{M!}{N!(M-N)!}, \text{(M=7, N=3)} $$

    可以用Python的程序来计算出这个值,代码如下所示。

    """
    输入M和N计算C(M,N)
    
    Version: 0.1
    Author: 骆昊
    """
    m = int(input('m = '))
    n = int(input('n = '))
    fm = 1
    for num in range(1, m + 1):
        fm *= num
    fn = 1
    for num in range(1, n + 1):
        fn *= num
    fm_n = 1
    for num in range(1, m - n + 1):
        fm_n *= num
    print(fm // fn // fm_n)

    函数的作用

    不知道大家是否注意到,在上面的代码中,我们做了3次求阶乘,这样的代码实际上就是重复代码。编程大师Martin Fowler先生曾经说过:“代码有很多种坏味道,重复是最坏的一种!”,要写出高质量的代码首先要解决的就是重复代码的问题。对于上面的代码来说,我们可以将计算阶乘的功能封装到一个称之为“函数”的功能模块中,在需要计算阶乘的地方,我们只需要“调用”这个“函数”就可以了。

    定义函数

    在Python中可以使用def关键字来定义函数,和变量一样每个函数也有一个响亮的名字,而且命名规则跟变量的命名规则是一致的。在函数名后面的圆括号中可以放置传递给函数的参数,这一点和数学上的函数非常相似,程序中函数的参数就相当于是数学上说的函数的自变量,而函数执行完成后我们可以通过return关键字来返回一个值,这相当于数学上说的函数的因变量。

    在了解了如何定义函数后,我们可以对上面的代码进行重构,所谓重构就是在不影响代码执行结果的前提下对代码的结构进行调整,重构之后的代码如下所示。

    """
    输入M和N计算C(M,N)
    
    Version: 0.1
    Author: 骆昊
    """
    def fac(num):
        """求阶乘"""
        result = 1
        for n in range(1, num + 1):
            result *= n
        return result
    
    
    m = int(input('m = '))
    n = int(input('n = '))
    # 当需要计算阶乘的时候不用再写循环求阶乘而是直接调用已经定义好的函数
    print(fac(m) // fac(n) // fac(m - n))

    说明: Python的math模块中其实已经有一个名为factorial函数实现了阶乘运算,事实上求阶乘并不用自己定义函数。下面的例子中,我们讲的函数在Python标准库已经实现过了,我们这里是为了讲解函数的定义和使用才把它们又实现了一遍,实际开发中并不建议做这种低级的重复劳动

    函数的参数

    函数是绝大多数编程语言中都支持的一个代码的"构建块",但是Python中的函数与其他语言中的函数还是有很多不太相同的地方,其中一个显著的区别就是Python对函数参数的处理。在Python中,函数的参数可以有默认值,也支持使用可变参数,所以Python并不需要像其他语言一样支持函数的重载,因为我们在定义一个函数的时候可以让它有多种不同的使用方式,下面是两个小例子。

    from random import randint
    
    
    def roll_dice(n=2):
        """摇色子"""
        total = 0
        for _ in range(n):
            total += randint(1, 6)
        return total
    
    
    def add(a=0, b=0, c=0):
        """三个数相加"""
        return a + b + c
    
    
    # 如果没有指定参数那么使用默认值摇两颗色子
    print(roll_dice())
    # 摇三颗色子
    print(roll_dice(3))
    print(add())
    print(add(1))
    print(add(1, 2))
    print(add(1, 2, 3))
    # 传递参数时可以不按照设定的顺序进行传递
    print(add(c=50, a=100, b=200))

    我们给上面两个函数的参数都设定了默认值,这也就意味着如果在调用函数的时候如果没有传入对应参数的值时将使用该参数的默认值,所以在上面的代码中我们可以用各种不同的方式去调用add函数,这跟其他很多语言中函数重载的效果是一致的。

    其实上面的add函数还有更好的实现方案,因为我们可能会对0个或多个参数进行加法运算,而具体有多少个参数是由调用者来决定,我们作为函数的设计者对这一点是一无所知的,因此在不确定参数个数的时候,我们可以使用可变参数,代码如下所示。

    # 在参数名前面的*表示args是一个可变参数
    def add(*args):
        total = 0
        for val in args:
            total += val
        return total
    
    
    # 在调用add函数时可以传入0个或多个参数
    print(add())
    print(add(1))
    print(add(1, 2))
    print(add(1, 2, 3))
    print(add(1, 3, 5, 7, 9))

    用模块管理函数

    对于任何一种编程语言来说,给变量、函数这样的标识符起名字都是一个让人头疼的问题,因为我们会遇到命名冲突这种尴尬的情况。最简单的场景就是在同一个.py文件中定义了两个同名函数,由于Python没有函数重载的概念,那么后面的定义会覆盖之前的定义,也就意味着两个函数同名函数实际上只有一个是存在的。

    def foo():
        print('hello, world!')
    
    
    def foo():
        print('goodbye, world!')
    
    
    # 下面的代码会输出什么呢?
    foo()

    当然上面的这种情况我们很容易就能避免,但是如果项目是由多人协作进行团队开发的时候,团队中可能有多个程序员都定义了名为foo的函数,那么怎么解决这种命名冲突呢?答案其实很简单,Python中每个文件就代表了一个模块(module),我们在不同的模块中可以有同名的函数,在使用函数的时候我们通过import关键字导入指定的模块就可以区分到底要使用的是哪个模块中的foo函数,代码如下所示。

    module1.py

    def foo():
        print('hello, world!')

    module2.py

    def foo():
        print('goodbye, world!')

    test.py

    from module1 import foo
    
    # 输出hello, world!
    foo()
    
    from module2 import foo
    
    # 输出goodbye, world!
    foo()

    也可以按照如下所示的方式来区分到底要使用哪一个foo函数。

    test.py

    import module1 as m1
    import module2 as m2
    
    m1.foo()
    m2.foo()

    但是如果将代码写成了下面的样子,那么程序中调用的是最后导入的那个foo,因为后导入的foo覆盖了之前导入的foo

    test.py

    from module1 import foo
    from module2 import foo
    
    # 输出goodbye, world!
    foo()

    test.py

    from module2 import foo
    from module1 import foo
    
    # 输出hello, world!
    foo()

    需要说明的是,如果我们导入的模块除了定义函数之外还中有可以执行代码,那么Python解释器在导入这个模块时就会执行这些代码,事实上我们可能并不希望如此,因此如果我们在模块中编写了执行代码,最好是将这些执行代码放入如下所示的条件中,这样的话除非直接运行该模块,if条件下的这些代码是不会执行的,因为只有直接执行的模块的名字才是"__main__"。

    module3.py

    def foo():
        pass
    
    
    def bar():
        pass
    
    
    # __name__是Python中一个隐含的变量它代表了模块的名字
    # 只有被Python解释器直接执行的模块的名字才是__main__
    if __name__ == '__main__':
        print('call foo()')
        foo()
        print('call bar()')
        bar()

    test.py

    import module3
    
    # 导入module3时 不会执行模块中if条件成立时的代码 因为模块的名字是module3而不是__main__

    练习

    练习1:实现计算求最大公约数和最小公倍数的函数。

    参考答案:

    def gcd(x, y):
        """求最大公约数"""
        (x, y) = (y, x) if x > y else (x, y)
        for factor in range(x, 0, -1):
            if x % factor == 0 and y % factor == 0:
                return factor
    
    
    def lcm(x, y):
        """求最小公倍数"""
        return x * y // gcd(x, y)

    练习2:实现判断一个数是不是回文数的函数。

    参考答案:

    def is_palindrome(num):
        """判断一个数是不是回文数"""
        temp = num
        total = 0
        while temp > 0:
            total = total * 10 + temp % 10
            temp //= 10
        return total == num

    练习3:实现判断一个数是不是素数的函数。

    参考答案:

    def is_prime(num):
        """判断一个数是不是素数"""
        for factor in range(2, int(num ** 0.5) + 1):
            if num % factor == 0:
                return False
        return True if num != 1 else False

    练习4:写一个程序判断输入的正整数是不是回文素数。

    参考答案:

    if __name__ == '__main__':
        num = int(input('请输入正整数: '))
        if is_palindrome(num) and is_prime(num):
            print('%d是回文素数' % num)

    注意:通过上面的程序可以看出,当我们将代码中重复出现的和相对独立的功能抽取成函数后,我们可以组合使用这些函数来解决更为复杂的问题,这也是我们为什么要定义和使用函数的一个非常重要的原因。

    变量的作用域

    最后,我们来讨论一下Python中有关变量作用域的问题。

    def foo():
        b = 'hello'
    
        # Python中可以在函数内部再定义函数
        def bar():
            c = True
            print(a)
            print(b)
            print(c)
    
        bar()
        # print(c)  # NameError: name 'c' is not defined
    
    
    if __name__ == '__main__':
        a = 100
        # print(b)  # NameError: name 'b' is not defined
        foo()

    上面的代码能够顺利的执行并且打印出100、hello和True,但我们注意到了,在bar函数的内部并没有定义ab两个变量,那么ab是从哪里来的。我们在上面代码的if分支中定义了一个变量a,这是一个全局变量(global variable),属于全局作用域,因为它没有定义在任何一个函数中。在上面的foo函数中我们定义了变量b,这是一个定义在函数中的局部变量(local variable),属于局部作用域,在foo函数的外部并不能访问到它;但对于foo函数内部的bar函数来说,变量b属于嵌套作用域,在bar函数中我们是可以访问到它的。bar函数中的变量c属于局部作用域,在bar函数之外是无法访问的。事实上,Python查找一个变量时会按照“局部作用域”、“嵌套作用域”、“全局作用域”和“内置作用域”的顺序进行搜索,前三者我们在上面的代码中已经看到了,所谓的“内置作用域”就是Python内置的那些标识符,我们之前用过的inputprintint等都属于内置作用域。

    再看看下面这段代码,我们希望通过函数调用修改全局变量a的值,但实际上下面的代码是做不到的。

    def foo():
        a = 200
        print(a)  # 200
    
    
    if __name__ == '__main__':
        a = 100
        foo()
        print(a)  # 100

    在调用foo函数后,我们发现a的值仍然是100,这是因为当我们在函数foo中写a = 200的时候,是重新定义了一个名字为a的局部变量,它跟全局作用域的a并不是同一个变量,因为局部作用域中有了自己的变量a,因此foo函数不再搜索全局作用域中的a。如果我们希望在foo函数中修改全局作用域中的a,代码如下所示。

    def foo():
        global a
        a = 200
        print(a)  # 200
    
    
    if __name__ == '__main__':
        a = 100
        foo()
        print(a)  # 200

    我们可以使用global关键字来指示foo函数中的变量a来自于全局作用域,如果全局作用域中没有a,那么下面一行的代码就会定义变量a并将其置于全局作用域。同理,如果我们希望函数内部的函数能够修改嵌套作用域中的变量,可以使用nonlocal关键字来指示变量来自于嵌套作用域,请大家自行试验。

    在实际开发中,我们应该尽量减少对全局变量的使用,因为全局变量的作用域和影响过于广泛,可能会发生意料之外的修改和使用,除此之外全局变量比局部变量拥有更长的生命周期,可能导致对象占用的内存长时间无法被垃圾回收。事实上,减少对全局变量的使用,也是降低代码之间耦合度的一个重要举措,同时也是对迪米特法则的践行。减少全局变量的使用就意味着我们应该尽量让变量的作用域在函数的内部,但是如果我们希望将一个局部变量的生命周期延长,使其在定义它的函数调用结束后依然可以使用它的值,这时候就需要使用闭包,这个我们在后续的内容中进行讲解。

    说明: 很多人经常会将“闭包”和“匿名函数”混为一谈,但实际上它们并不是一回事,如果想了解这个概念,可以看看维基百科的解释或者知乎上对这个概念的讨论。

    说了那么多,其实结论很简单,从现在开始我们可以将Python代码按照下面的格式进行书写,这一点点的改进其实就是在我们理解了函数和作用域的基础上跨出的巨大的一步。

    def main():
        # Todo: Add your code here
        pass
    
    
    if __name__ == '__main__':
        main()
    展开全文
  • 06.函数和模块的使用

    2020-02-10 07:12:42
    事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。 可以用Python的程序来计算出这个值,代码如下所示。 """ 输入M和N计算C(M,N) Version: 0.1 Author:...
  • 带你搭一个SpringBoot+SpringData JPA的Demo 【极简版】SpringBoot+SpringData JPA 管理系统 外行人都能看懂的WebFlux,错过了血亏 WebFlux学习时常见的问题 :lollipop:SSM项目 SSM【史上最详细整合】 Java高并发...
  • 事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。 可以用Python的程序来计算出这个值,代码如下所示。 """ 输入M和N计算C(M,N) """ m = int(input('m...
  • 参数同“以单个铜公开料”一样,但在选择铜公上是条地选择的,您有多少条铜公需要开料就要选择多少次,选择完后按选择的“取消”按扭或“Esc”键退出选择。 5.出放电数: ①大众化的 EDM 图纸:这是为了广大...
  • 这是一个1x1英寸的PCB模块,带两个微型太阳能电池,一个高效的锂离子电池充电器和两个稳压输出(3.3V和1.8V)。它是独一无二的,因为它是一个易于制造的微型模块,其他黑客可以放入他们的PCB设计或面包板。...
  • 事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。 可以用Python的程序来计算出这个值,代码如下所示。 """ 输入M和N计算C(M,N) Version: 0.1 Author:...
  • 将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。 可以用Python的程序来计算出这个值,代码如下所示。 """ 输入M和N计算C(M,N) Version: 0.1 Author: 范恒宾 """ m = int(input...
  • 事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。可以用Python的程序来计算出这个值,代码如下所示。""" 输入M和N计算C(M,N) """ m = int(input('m = ...
  • 事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。 可以用Python的程序来计算出这个值,代码如下所示。 """ 输入M和N计算C(M,N) """ m = int...
  • 事实上,上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。 可以用Python的程序来计算出这个值,代码如下所示。 """ 输入M和N计算C(M,N) ...
  • k: number of neighbors to use for comparison (should be an odd number)有多少属性 Output: the most popular class label @author: pbharrin ''' from numpy import * import operator from os ...
  • 3.BFD-1000 有一个专门设计的触碰传感器,使得这方面的需求机器人设计更加简便。 4.BFD-1000 输出信号全部都为数字信号,方便与单片机相连。 5.BFD-1000 全部传感器都LED 灯作为指示,方便调试 6.BFD-1000 支持...
  • 故事看这里:背景故事 (链接) 作业 这个游戏可以变成一个持续发展的团队项目: 1)在课堂上玩这个黄金游戏,用Excel 纪录成绩。...前面写的模块有多少是可以重用的? 为何不能重用? 研讨 cli...
  • 门窗工厂软件

    2018-11-12 14:32:27
    手工算单,旺季加班加点也干不完,出错率也高,淡季人员闲置照拿工资,几个月培训一个技术员 ,刚上手又走了;用智木门生产算料软件输入订单参数,马上就算出来了。且一劳永逸,一次性测试准确了,后面再也不会...
  • 一卡通软件

    2015-03-11 16:15:22
    3) 一个按钮完成一个人的人卡资料添加并继续操作下一个,全部完成后确认退出; 4) 人事资料添加完毕后,可直接选择未发卡人员,鼠标右键→发卡,或通过 “卡片中心”→“发卡”,选择未发卡人员,鼠标右键...
  • 3.一个源程序不论由多少个文件组成,都有一个且只能有一个main函数,即主函数。 4.源程序中可以预处理命令(include 命令仅为其中的一种),预处理命令通常应放在源文件或源程序的最前面。 5.每一个说明,每一个语句...
  • 入门学习Linux常用必会60命令实例详解doc/txt

    千次下载 热门讨论 2011-06-09 00:08:45
    所以这个选项当然没有时间参数,但是可以输入一个用来解释的讯息,而这信息将会送到每位使用者。 -F:在重启计算机时强迫fsck。 -time:设定关机前的时间。 -m: 将系统改为单用户模式。 -i:关机时显示系统...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 135
精华内容 54
关键字:

一个输入模块有多少点