精华内容
下载资源
问答
  • 计算1到n的和,n的值通过参数传递,求答案 求答案求答案求答案
  • 提高代码质量:如何编写函数 阅读目录 命名 函数参数 编写函数体 总结 函数是实现程序功能的最基本单位,每一个程序都是由一个个最基本的函数构成的。写好一个函数是提高程序代码质量最关键的...

    提高代码质量:如何编写函数

    函数是实现程序功能的最基本单位,每一个程序都是由一个个最基本的函数构成的。写好一个函数是提高程序代码质量最关键的一步。本文就函数的编写,从函数命名,代码分布,技巧等方面入手,谈谈如何写好一个可读性高、易维护,易测试的函数。

    命名

    首先从命名说起,命名是提高可读性的第一步。如何为变量和函数命名一直是开发者心中的痛点之一,对于母语非英语的我们来说,更是难上加难。下面我来说说如何为函数命名的一些想法和感受:

    采用统一的命名规则

    在谈及如何为函数取一个准确而优雅的名字之前,首先最重要的是要有统一的命名规则。这是提高代码可读性的最基础的准则。
    帕斯卡命名法和驼峰命名法是目前比较流行的两种规则,不同语言采用的规则可能不一样,但是要记住一点:保持团队和个人风格一致。
    1、帕斯卡命名法
    帕斯卡命名法简单地说就是:多个单词组成一个名称时,每个单词的首字母大写。比如:

    1 public void SendMessage ();
    2 public void CalculatePrice ();

    在C#中,这种命名法常用于类、属性,函数等等,在JS中,构造函数也推荐采用这种方式命名。

    2、驼峰命名法
    驼峰命名法和帕斯卡命名法很类似,多个单词组成一个名称时,第一个单词全部小写,后面单词首字母大写。比如:

    1 var sendMessage = function () {};
    2 var calculatePrice = function () {};

    驼峰命名法一般用于字段、局部变量、函数参数等等。,在JS中,函数也常用此方法命名。

    采用哪种命名规则并不绝对,最重要的是要遵守团队约定,语言规范。

    尽可能完整地描述函数所做的所有事情

    有的开发者可能觉得相较于长函数名来说,短函数名看起来可能更简洁,看起来也更舒服。但是通常来说,函数名称越短其描述的意思越抽象。函数使用者对函数的第一印象就是函数名称,进而了解函数的功能,我们应该尽可能地描述到函数所做的所有事情,防止使用者不知道或误解造成潜在的错误。
    举个例子,假设我们做一个添加评论的功能,添加完毕后并返回评论总数量,如何命名比较合适呢?

    1 // 描述不够完整的函数名
    2 var count = function addComment() {};
    3 
    4 // 描述完整的函数名
    5 var count = function addCommentAndReturnCount() {};

    这只是简单的一个例子,实际开发中可能会遇到得更多复杂的情况,单一职责原则是我们开发函数要遵守的准则,但是有时候无法做到函数单一职责时,请记得函数名应该尽可能地描述所有事情。当你无法命名一个函数时,应该分析一下,这个函数的编写是否科学,有什么办法可以去优化它。

    采用准确的描述动词

    这一点对母语非英语的开发者来说应该是比较难的一点,想要提高这方面的能力,最主要的还是要提高词汇量,多阅读优秀代码积累经验。
    这里简单说说我自己的一些感想和看法:
    1、不要采用太抽象广泛的单词
    很多开发人员会采用一个比较宽泛的动词来为函数命名,最典型的一个例子就是get这个单词。我们平时开发中经常会通过各种不同的方式拿到数据,但是每一种方式都用get就有点太抽象了。具体如何命名,要具体分析:
    (1)简单的返回数据

    1 Person.prototype.getFullName = function() {
    2     return this.firstName = this.lastName;
    3 }

    (2)从远程获取数据

    1 var fetchPersons = function () {
    2     ...
    3     $.ajax({
    4     })
    5 }

    (3)从本地存储加载数据

    1 var loadPersons = function () {};

    (4)通过计算获取数据

    1 var calculateTotal = function () {};

    (5)从数组中查找数据

    1 var findSth = function (arr) {};

    (6)从一些数据生成或得到

    1 var createSth = function (data) {};
    2 var buildSth = function (data) {};
    3 var parseSth = function(data) {};

    这是一个简单的例子,我们平时开发中遇到的情况肯定会复杂得多,关键还是靠单词的积累,多阅读优秀源码

    下面是整理的一些常用的对仗词,大家可以参考使用

    复制代码
    复制代码
    1 add/remove        increment/decrement       open/close
    2 begin/end            insert/delete                      show/hide
    3 create/destory    lock/unlock                        source/target
    4 first/last              min/max                             star/stop
    5 get/put                next/previous                     up/down     
    6 get/set                old/new
    复制代码
    复制代码

    根据不同项目和需求制定好命名规则

    这一点也是很重要的,尤其是在团队合作中,不同的项目和需求可能导致的不同的命名规则。
    比如我们通常采用的命名规则是动宾结构,也就是动词在前,名词灾后。但是有一些项目,比如数据接口等项目中,有的团队会采用名字在前,动词在后的形式,例如:

    1 public static Product[] ProductsGet(){};
    2 public static Product[] ProductsDel(){};
    3 public static Customer[] CustomerDel(){};
    4 public static Customer[] CustomerDel(){};

    这种的好处是看到前面的名词,比如ProductsGet,就能很快的知道这是产品相关的数据接口。
    当然这个并不是绝对的,关键还是要团队共同制定和遵守同一套命名规则。

    函数参数

    函数使用者在调用函数时,必须严格遵守函数定义的参数,这对函数的易用性,可测试性等方面都是至关重要的。下面我从几个方面来谈谈关于如何优化好函数参数的一些想法。

    参数数量

    毫无疑问,函数参数越多,函数的易用性就越差,因为使用者需要严格眼中参数列表依次输入参数,如果某个参数输错,将导致不可意料的结果。
    但是,函数参数就一定越少越好吗?我们来看看下面的例子:

    复制代码
    复制代码
    1 var count = 0;
    2 var unitPrice = 1.5;
    3 ....
    4 ...
    5 var calculatePrice = function () {
    6     return count * unitPrice;
    7 }
    复制代码
    复制代码

    在这个例子中,我们通过calculatePrice这个函数来计算价格,函数不接收任何参数,直接通过两个全局变量unitPrice和count进行计算。这种函数的定义对使用者来说非常方便,直接调用即可,不用输入任何参数。但是这里可能会有潜在的bug:全局变量可能在其他地方被修改成其他值了,难以进行单元测试等等问题。所以,这个函数可以传入数量和价格信息:

    1 var calculatePrice = function(count, unitPrice) {
    2     return count * unitPrice;
    3 }

    这种方式下,函数使用者在使用时,要传入参数进行调用,避免了全局变量可能存在的问题。另外也降低了耦合,提高了可测试性,在测试的时候就不必依赖于全局变量。

    当然,在保证函数不依赖于全局变量和测试性的情况下,函数参数还是越少越好。《代码大全》中提出将函数的参数限制在7个以内,这个可以作为我们的参考。
    有的时候,我们不可避免地要使用超过10个以上函数,在这中情况下,我们可以考虑将类似的参数构造成一个类,我们来看看一个典型的例子。
    我相信大家平时一定做过这样的功能,列表筛选,其中涉及到各种条件的筛选,排序,分页等等功能,如果将参数一个一个地列出来必定会很长,例如:

    1 var filterHotel = function (city, checkIn, checkOut, price, star, position, wifi, meal, sort, pageIndex) {}

    这是一个筛选酒店的函数,其中的参数分别是城市,入住和退房时间,价格,星级,位置,是否有wifi,是否有早餐,排序,页码等等,实际的情况可能会更多。在这种参数特别多的情况下,我们可以考虑将一些相似的参数提取成类出来:

    复制代码
    复制代码
     1 function DatePlace (city, checkIn, checkOut){
     2     this.city = city;
     3     this.checkIn = checkIn;
     4     this.checkOut = checkOut
     5 }
     6 
     7 function HotelFeature (price, star, position, wifi, meal){
     8     this.price = price;
     9     this.star = star;
    10     this.position = position;
    11     this.wifi = wifi;
    12     this.meal = meal;
    13 }
    14 
    15 var filterHotel = function (datePlce, hotelFeature, sort, pageIndex) {};
    复制代码
    复制代码

    将多个参数提取成对象了,虽然对象数量增多了,但是函数参数更清晰了,调用起来也更方便了。

    尽量不要使用bool类型作为参数

    有的时候,我们会写出使用bool作为参数的情况,比如:

    复制代码
    复制代码
    1 var getProduct = function(finished) {
    2     if(finished){
    3     }
    4     else{
    5     }
    6 }
    7 
    8 // 调用
    9 getProduct(true);
    复制代码
    复制代码

    如果没有注释,使用者看到这样的代码:getProduct(true),他肯定搞不清楚true是代表什么意思,还要去查看函数定义才能明白这个函数是如何使用的。这就意味着这个函数不够清晰,就应该考虑去优化它。通常有两种方式去优化它:
    (1)将函数一分为二,分成两个函数getFinishedProduct和getUnFinishedProduct
    (2)将bool转换成有意义的枚举getProduct(ProductStatus)

    不要修改输入参数

    如果输入参数在函数内被修改了,很有可能造成潜在的bug,而且使用者不知道调用函数后居然会修改函数参数。
    正确使用输入参数的做法应该是只传入参数用于函数调用。
    如果不可避免地要修改,一定要在注释中说明。

    尽量不要使用输出参数

    使用输出参数说明这个函数不只做了一件事情,而且使用者使用的时候可能还会感到困惑。正确的方式应该是分解函数,让函数只做一件事。

    编写函数体

    函数体就是实现函数功能的整个逻辑,是一个函数最关键的地方。下面我谈谈关于函数代码编写的一些个人想法。

    相关操作放在一起

    有的时候,我们会在一个函数内进行一系列的操作来完成一个功能,比如:

    复制代码
    复制代码
    1 var calculateTotalPrice = function()  {
    2     var roomCount = getRoomCount();
    3     var mealCount = getMealCount();
    4 
    5     var roomPrice = getRoomPrice(roomCount);
    6     var mealPrice = getMealPrice(mealCount);
    7 
    8     return roomPrice + mealPrice;
    9 }
    复制代码
    复制代码

    这段代码计算了房间价格和早餐价格,然后将两者相加返回总价格。
    这段代码乍一看,没有什么问题,但是我们分析代码,我们先是分别获取了房间数量和早餐数量,然后再通过房间数量和早餐数量分别计算两者的价格。这种情况下,房间数量和计算房间价格的代码分散在了两个位置,早餐价格的计算也是分散到了两个位置。也就是两部分相关的代码分散在了各处,这样阅读起代码来逻辑会略显不通,代码组织不够好。我们应该让相关的语句和操作放在一起,也有利于重构代码。我们修改如下:

    复制代码
    复制代码
    1 var calculateTotalPrice = function()  {
    2     var roomCount = getRoomCount();
    3     var roomPrice = getRoomPrice(roomCount);
    4 
    5     var mealCount = getMealCount();
    6     var mealPrice = getMealPrice(mealCount);
    7 
    8     return roomPrice + mealPrice;
    9 }
    复制代码
    复制代码

    我们将相关的操作放在一起,这样代码看起来更清晰了,而且也更容易重构了。

    尽量减少代码嵌套

    我们平时写if,switch或for语句是常有的事儿,也一定写过多层if或for语句嵌套的情况,如果代码里的嵌套超过3层,阅读起来就会非常困难了。我们应该尽量避免代码嵌套多层,最好不要超过2层。下面我来说说我平时一些减少嵌套的技巧或方法。

    if语句嵌套的问题

    多层if语句嵌套是常有的事情,有什么好的方法可以减少嵌套呢?
    1、尽早终止函数或返回数据
    如果符合某个条件下可以直接终止函数,则应该将这个条件放在第一位。我们来看看下面的例子。

    复制代码
    复制代码
     1 if(condition1) {
     2     if(condition2){
     3         if(condition3){
     4         }
     5         else{
     6             return;
     7         }    
     8     }
     9     else{
    10         return;
    11     }    
    12 }
    13 else {
    14     return;
    15 }
    复制代码
    复制代码

    这段代码中if语句嵌套了3层,看起来已经很复杂了,我们可以将最后面的return提取到最前面去。

    复制代码
    复制代码
     1 if(!condition1){
     2     return;
     3 }
     4 if(!condition2){
     5     return;
     6 }
     7 if(!condition3){
     8     return;
     9 }
    10 //doSth
    复制代码
    复制代码

    这段代码中,我们把condition1等于false的语句提取到前面,直接终止函数,将多层嵌套的if语句重构成只有一层if语句,代码也更清晰了。

    注意:一般情况下,我们写if语句会将条件为true的情况写在前面,这也比较符合我们的思维习惯。如果是多层嵌套的情况,应该优先减少if语句的嵌套

    2、不适用if语句或switch语句
    条件语句一般来说是不可避免的,有的时候,我们要判断很多条件就会写很多if-elseif语句,嵌套的话,就更加麻烦了。如果有一天增加了新需求,我们就要去增加一个if分支语句,这样不仅修改起来麻烦,而且容易出错。《代码大全》提出的表驱动法可以有效地解决if语句带来的问题。我们来看下面这个例子:

    复制代码
    复制代码
     1 if(condition == “case1”){
     2     return 1;
     3 }
     4 elseif(condition == “case2”){
     5     return 2;
     6 }
     7 elseif(condition == “case3”){
     8     return 3;
     9 }
    10 elseif(condition == “case4”){
    11     return 4;
    12 }
    复制代码
    复制代码

    这段代码分别依次判断了四种情况,如果再增加一种情况,我们就要再新增一个if分支,这样就可能造成潜在的问题,如何去优化这段代码呢?我们可以采用一个Map或Dictionary来将每一种情况和相应值一一对应。

    复制代码
    复制代码
    1 var map = {
    2     "case1":1,
    3     "case2":2,
    4     "case3":3,
    5     "case4":4
    6 }
    7 return map[condition];
    复制代码
    复制代码

    通过map优化后,整个代码不仅更加简洁,修改起来也更方便而且不易出错了。
    当然,很多时候我们的条件判断语句并不是这么简单的,可能会涉及到复杂的逻辑运算,大家可以查看《代码大全》第18章,其中有详细的介绍。

    3、提取内层嵌套为一个函数进行调用
    多层嵌套的时候,我们还可以将内层嵌套提取到一个新的函数中,然后调用该函数,这样代码也就更清晰了。

    for循环嵌套优化

    for循环嵌套相比于if嵌套来说更加复杂,阅读起来会更麻烦,下面说说几点要注意的东西:
    1、最多只能两层for循环嵌套
    2、提取内层循环到新函数中
    3、多层循环时,不要简单地位索引变量命名为i,j,k等,容易造成混淆,要有具体的意思

    提取复杂逻辑,语义化

    有的时候,我们会写出一些比较复杂的逻辑,阅读代码的人看到后可能搞不清楚要做什么,这个时候,就应该提取出这段复杂的逻辑代码。

    1 if (age > 18 && gender == "man") {
    2     //doSth
    3 }

    这段代码表示当年龄大于18并且是男性的话,可以doSth,但是还是不够清晰,可以将其提取出来

    复制代码
    复制代码
    1 var canDoSth = function (age, gender){
    2     return age > 18 && gender == "man";
    3 }
    4 ...
    5 ...
    6 ...
    7 if(canDoSth(age, gender)){
    8     //doSth
    9 }
    复制代码
    复制代码

    虽说多了一个函数,但是代码更加清晰和语义化了。

    总结

    本文从函数命名,函数参数和函数的代码编写三个方面谈了关于如何编写好一个函数的感受和想法。文中提到了很多具体的情况,当然日常编码中肯定会遇到更多复杂的情况可能我暂时没有想到。我简单的归纳了几点:
    1、准确地对变量、函数命名
    2、不要有重复逻辑的代码
    3、函数的行数不要超过20行,这里的20行只是个大概,并不一定是这个数字
    4、减少嵌套
    我相信大家一定会很多关于这方面的经验,欢迎进行交流,共同提高代码质量。

     

    本文地址:http://luopq.com/2016/02/21/write-good-function/,转载

    转载于:https://www.cnblogs.com/gh0408/p/6058554.html

    展开全文
  • 学习如何编写函数

    2020-11-06 12:44:36
    学习编写函数 函数是带名字的代码块,用于完成具体的工作。要执行函数定义的特定任务,可调用该函数。 (一)定义函数 我们先来看一个最简单的函数结构: def greet_user(): '''这是一个简单的问候语''' print('...

    学习编写函数

                                                                                                 作者:雷蕾
    

    函数是带名字的代码块,用于完成具体的工作。要执行函数定义的特定任务,可调用该函数。
    (一)定义函数
    我们先来看一个最简单的函数结构:

    def greet_user(): 
        '''这是一个简单的问候语'''
        print('Hello')
    greet_user()
    

    我们试着来解读这段代码:第一行代码行使用关键字def来告诉python,我要定义一个函数,向python指定函数名为greet_user,还可以在圆括号内指出函数为完成任务需要什么样的信息,因为在这次代码中,我们不需要任何信息就能完成工作,因此圆括号内是空的,最后以冒号结束。
    紧跟在def greet_user():后面的所有缩进构成了函数体, ‘’‘这是一个简单的问候语’’'称为文档字符串的注释,描述了该函数是做什么。文档字符串用三引号括起。
    第三行代码: print(‘Hello’)是函数体内唯一一行代码,因此greet_user()只做一项工作:打印Hello。
    第四行代码是调用函数,要调用函数,可依次指出函数名以及用圆括号括起来的必要信息,在这次代码中,调用函数只要输入greet_user()就可以。
    运行结果:

    Hello
    

    (二)向函数传递信息
    我们先来看一段简单的代码:

    def greet_user(username): 
        '''这是一个简单的问候语''' 
        print(f'Hello,{username.title()}')
    greet_user('sarah')
    

    和上个示例不同,这次我们不仅让greet_user()能完成打印Hello的任务,还能将用户的名字打印。
    我们在函数定义def greet_user()的括号内添加了username,通过添加,可让函数接受我们给username指定的任何值。
    第一行代码就是要求你调用它时给username指定一个值。
    第四行代码调用函数greet_user()时,将’sarah’传递给了它。
    运行结果:

    Hello,Sarah
    

    还有一点就是我们都很容易形参、实参不分,那该如何区分形参和实参呢?
    在上述代码中,def greet_user(username):圆括号内的username就是形参,即函数完成任务所需要的信息,greet_user(‘sarah’)圆括号内的’sarah’就是实参,即调用函数时传递给它的信息,实参’sarah’被赋给了形参username。
    (三)传递实参
    我们在定义函数时可能包括多个形参,相应地,我们也应该将多个实参赋给形参。
    向函数传递实参的方法主要有这几种方式:
    (1)位置实参
    (2)关键字实参
    (3)使用列表和字典
    我们来学习位置实参,先看两个示例代码以及运行结果
    示例1:

    def describe_pet(animal_type,animal_name):
        '''这是显示宠物的信息'''
        print(f"\ni have a {animal_type}")
        print(f"{animal_type}'s name is {animal_name}")
    describe_pet('hamster','harry')
    

    运行结果:

    i have a hamster
    hamster's name is harry
    

    示例2:

    def describe_pet(animal_type,animal_name):
        '''这是显示宠物的信息'''
        print(f"\ni have a{animal_type}")
        print(f"{animal_type}'s name is{animal_name}")
    describe_pet('harry','hamster')
    

    运行结果:

    i have a hamster
    hamster's name is hamster
    

    我们仔细观察两个示例的运行结果发现相反,调用函数时,python必须将函数调用中的每个实参都关联到函数定义中的每一个形参,但在函数调用时将两个实参赋给形参的顺序不一样导致最后的结果也不一样,由此我们可知:
    位置实参要求实参的顺序与形参的顺序相同,不然会导致逻辑错误。
    我们可以根据需要调用函数任意次:

    #传递实参
    #关键字实参
    def describe_pet(animal_type,animal_name):
        '''这是显示宠物的信息'''
        print(f"\ni have a {animal_type}")
        print(f"{animal_type}'s name is {animal_name}")
    describe_pet('hamster','harry')
    describe_pet('dog','willie')
    

    运行结果:

    i have a hamster
    hamster's name is harry
    
    i have a dog
    dog's name is willie
    

    关键字实参是传递给函数的名称值对,直接在实参中将名称和值关联起来。
    先看一段代码:

    def describe_pet(animal_type,animal_name):
        '''这是显示宠物的信息'''
        print(f"\ni have a {animal_type}")
        print(f"{animal_type}'s name is  {animal_name}")
    describe_pet(animal_type='hamster',animal_name='harry')
    describe_pet(animal_name='willie',animal_type='dog')
    

    运行结果:

    i have a  hamster
    hamster's name is harry
    
    i have a  dog
    dog's name is willie
    

    关键字实参让我们无需考虑函数调用的实参顺序,还能够清楚地指出了函数调用中各个值地用途。
    默认值:编写函数时,可给每个形参指定默认值。
    在调用函数时,我们给形参指定了实参,python会使用指定地实参值,否则会使用默认。

    def describe_pet(animal_name,animal_type='dog'):
        '''这是显示宠物的信息'''
        print(f"\ni have a  {animal_type}")
        print(f"{animal_type}'s name is  {animal_name}")
    describe_pet(animal_name='harry')
    describe_pet('willie')
    

    运行结果:

    i have a dog
    dog's name is harry
    
    i have a dog
    dog's name is willie
    

    但值得注意的一点是:使用默认值时,必须先在形参列表中列出没有默认值的形参,再列出有默认值的实参
    在进行函数调用时,我们要避免实参错误:形参与实参不匹配,这样的情况可能我们提供的实参多于或少于了形参数。

    def describe_pet(animal_type,animal_name):
        '''这是显示宠物的信息'''
        print(f"\ni have a{animal_type}")
        print(f"{animal_type}'s name is{animal_name}")
    describe_pet()
    

    运行结果:

       Traceback (most recent call last):
      File "C:\Users\12184\Desktop\pet.py", line 7, in <module>
        describe_pet()
    TypeError: describe_pet() missing 2 required positional arguments: 'animal_type' and 'animal_name'
    

    运行报错: Traceback指出了问题所在,它让我们回去找函数调用中的错误,也指出了该函数调用过程中少了两个实参并指出了两个相应形参的名称。
    (四)返回值
    函数返回的值称为返回值,在函数中,可使用return语句将值返回到调用函数的代码行。
    先看一个函数,它接受名和姓,并返回整洁的姓名:

    def get_formatted_name(first_name,last_name):
        '''返回整洁的姓名'''
        full_name=f"{first_name} {last_name}"
        return full_name.title() #将值返回到调用函数的代码行
    musician=get_formatted_name('jimin','hendrix')
    print(musician)
    

    运行结果:

    Jimin Hendrix
    

    试着解读这段代码:
    第一行函数get_formatted_name()的定义通过形参接受名和姓;
    第三行是将名和姓合一并赋给变量full_name;
    第四行将full_name的值首字母大写并返回到函数调用(第五行);
    第五行就是函数调用。
    我们还可以让实参变成可选的,前面有提到,当实参赋予形参值时,我们使用所赋予的,其他时候可使用默认值。

    #让实参变成可选的
    #可使用默认值让实参变成可选的
    def get_formatted_name(first_name,last_name,middle_name=''):
        '''返回整洁的姓名'''
        if middle_name:
            full_name=f"{first_name}  {middle_name} {last_name}"
            return full_name.title() #将值返回到调用函数的代码行
        else:
          full_name=f"{first_name}  {last_name}"
          return full_name.title() #将值返回到调用函数的代码行
    musician=get_formatted_name('jimin','lee','hendrix')
    print(musician)
    musician=get_formatted_name('jimin','hendrix')
    print(musician)
    

    运行结果:

    Jimin  Hendrix Lee
    Jimin  Hendrix
    

    值得注意的是:形参middle_name的默认值设置为空字符串,必须将其移到形参列表的末尾
    返回字典:
    函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。

    def bulid_person(first_name,last_name):
        '''返回一段字典,其中包含一个人的信息'''
        person={'first':first_name,'last':last_name}
        return person
    musician=bulid_peson('jimin','hendrix')
    print(musician)
    

    运行结果:

    {'first': 'jimin', 'last': 'hendrix'}
    

    结合使用函数和while循环:

    def get_formatted_name(first_name,last_name):
        '''返回整洁的姓名'''
        full_name=f"{first_name} {last_name}"
        return full_name.title()
    while True:
        print("\nplease tell me your name")
        f_name=input("first:")
        l_name=input("last:")
        formatted_name=get_formatted_name(f_name,l_name)
        print(f"hello,{formatted_name}")
    

    运行结果:

    please tell me your name
    first:lee
    last:willie
    hello,Lee Willie
    
    please tell me your name
    first:
    

    上述代码有一个缺陷就是会无限循环下去,我们是否能添加一段让循环停止的命令行呢?

    def get_formatted_name(first_name,last_name):
        '''返回整洁的姓名'''
        full_name=f"{first_name} {last_name}"
        return full_name.title()
    while True:
        print("\nplease tell me your name")
        f_name=input("first:")
        if f_name=='q': #输入q循环停止
            break
        l_name=input("last:")#输入q循环停止
        if l_name=='q':
            break
        formatted_name=get_formatted_name(f_name,l_name)
        print(f"hello,{formatted_name}")
    

    运行结果:

    please tell me your name
    first:lee
    last:willie
    hello,Lee Willie
    
    please tell me your name
    first:q
    >>> 
    

    我们通过添加下面两行简单的代码,当输入’q’是循环停止。

      if f_name=='q': #输入q循环停止
            break
    

    (五)传递列表
    假设我们用一个用户列表,我们现在我们需要向用户列表中的每一个用户问候:

    def greet_users(names):
        '''向列表中的每位用户发出简单的问候'''
        for name in names:
            print(f"hello,{name.title()}")
    usernames=['hanah','ty','margot']
    greet_users(usernames)
    

    运行结果:

    hello,Hanah
    hello,Ty
    hello,Margot
    

    我们将列表传递给函数后,函数可对其进行修改,我们先看一段不需要函数的情况下如何模拟打印过程:

    #首先创建一个列表,其中包含一些要打印的设计
    unprinted_designs=['phone case','robot pendant','dodecahedron']
    completed_models=[]
    #模拟打印每个设计,直到没有未打印的设计为止
    #打印每个设计后,都将其移到列表completed_models中
    while unprinted_designs:
        current_design=unprinted_designs.pop()
        completed_models.append(current_design)
        print(f"printing models: {current_design}")
    #显示打印好的所有模型
    for  completed_model in  completed_models:
        print(f"\nthe follwing models have been printed:{ completed_model}")
    

    运行结果:

    printing models: dodecahedron
    printing models: robot pendant
    printing models: phone case
    
    the follwing models have been printed:dodecahedron
    
    the follwing models have been printed:robot pendant
    
    the follwing models have been printed:phone case
    

    下面看一段在定义函数的情况下模拟打印过程:

    def print_models(unprinted_models,completed_models):
        '''
    模拟打印每个设计,直到没有未打印的设计为止
    打印每个设计后,都将移动到列表completed_models中
    '''
        while unprinted_models:
            current_design=unprinted_models.pop()
            completed_models.append(current_design)
            print(f"printing models: {current_design}")
    def show_completed_models(completed_models):
        '''现实打印好的所有模型'''
        for completed_model in completed_models:
            print(f"\nthe follwing models have been printed: {completed_model}")
    unprinted_models=['phone case','robot pendant','dodecahedron']
    completed_models=[]
    print_models(unprinted_models,completed_models)
    show_completed_models(completed_models)
    

    运行结果:

    printing models: dodecahedron
    printing models: robot pendant
    printing models: phone case
    
    the follwing models have been printed: dodecahedron
    
    the follwing models have been printed: robot pendant
    
    the follwing models have been printed: phone case
    

    上述两段代码的运行结果一模一样,但使用函数的版本,以后我们需要打印其他设计只需再次调用print_models()就可以。
    在上述使用函数的示例中,每个函数只负责一项具体的工作,print_models打印每一个设计,show_completed_models显示打印好的所有模型,这也使得程序看起来更加简洁明了。

    (六)传递任意数量的实参
    python允许函数从调用语句中收集任意数量的实参,当不知道函数需要接受多少个实参时,我们可对形参名使用*(星号)

    def make_pizza(*toppings):
        '''打印顾客点的所有配料'''
        print(toppings)
    make_pizza('pepperoni')
    make_pizza('mushroom','green peppers','extre chees')
    

    运行结果:

    ('pepperoni',)
    ('mushroom', 'green peppers', 'extre chees')
    

    形参名*toppings中的星号可以让python创建一个名为toppings的空元组,并将所有收到的所有值都封装在这个元组中。
    我们可将其变为一个循环,遍历toppings所存储的值:

    def make_pizza(*toppings):
        '''打印顾客点的所有配料'''
        for topping in toppings:
            print(topping)
    make_pizza('pepperoni')
    make_pizza('mushroom','green peppers','extre chees')
    

    运行结果:

    pepperoni
    mushroom
    green peppers
    extre chees
    

    结合使用位置实参和任意数量实参:

    def make_pizza(size,*toppings):
        '''打印顾客点的所有配料'''
        print(f"\nmake a {size} pizza with the following toppings:")
        for topping in toppings:
            print(topping)
    make_pizza(12,'pepperoni')
    make_pizza(16,'mushroom','green peppers','extre chees')
    

    运行结果:

    make a 12 pizza with the following toppings:
    pepperoni
    
    make a 16 pizza with the following toppings:
    mushroom
    green peppers
    extre chees
    

    使用任意数量的关键字实参:

    def bulid_profile(first,last,**user_info):
        '''创建一个字典,其中包含我们所知道的有关用户的一切'''
        user_info['first']=first
        user_info['last']=last
        return user_info
    user_profile=bulid_profile('albert','einstein',
                               location='princeton',
                               field='phycics'
                               )
    print(user_profile)
    

    运行结果:

    {'location': 'princeton', 'field': 'phycics', 'first': 'albert', 'last': 'einstein'}
    

    形参**user_info中的两个星号让python创建一个名为user_info的空字典,并将收到的所有名字存储在这个字典中。

    展开全文
  • Now,let‘s go on,to conquer the C++!This is new chapter,chapter 2. ...如何编写函数 每一个自定义函数必须定义以下四个部分 返回类型,就是你想返回什么类型的变量你就些什么返回类型即可...

    Now,let‘s go on,to conquer the C++!This is new chapter,chapter 2.

    首先,你为什么要编写自定义函数?

    1. 以一连串函数调用操作,可以让程序能被读明白
    2. 我们可以在不同的程序中调用这些函数
    3. 可以更容易的将工作分配给协作开发团队

    如何编写函数

    每一个自定义函数必须定义以下四个部分

    1. 返回类型,就是你想返回什么类型的变量你就些什么返回类型即可
    2. 函数名,这个你随便定义,但你得学会定义能让人理解的函数名
    3. 参数列表,函数参数扮演者占位符的角色,在函数名后的()中列出,即类型名 变量名
    4. 函数体,紧接在参数列表后的大括号{ }括起来的那玩意儿

    这四个部分必不可少

    • 函数声明:函数声明不必提供函数体,但必须提供返回类型、函数名、参数列表,这些必须提供的组合起来称为函数原型
    • 函数定义:包括函数原型及函!数!体!
      所以我们不难看出函数声明与函数定义的区别,不要给混为一谈了。
    • 注释的第二种形式,即为/*注释内容*/ ,这个开始注释标志和结束注释标志可以跨行,这是"//“注释符不能做到的,所以跨行注释请用/*和*/(可以用来注释一些代码块或者自定义函数。一行注释请用"//"
    • 时刻考虑好程序的鲁棒性,因为用户可能瞎输入一个值给程序,此时你程序可以这样消化这个值
      标准库的exit()函数(用该函数时请写#include<cstdlib>),你写进exit()括号里的值就是程序结束时的状态值。一般来说,exit(0) 可以告知你的程序的使用者:你的程序是正常结束的。如果 exit 括号里是非 0 值,那么你的程序的使用者通常会认为你的程序产生了一个错误,也就是用户输入的有问题导致程序异常结束。
      摘自百度百科——Exit()
      exit(0)表示正常退出,
      exit(x)(x不为0)都表示异常退出,这个x是返回给操作系统(包括UNIX,Linux,和MS DOS)的,以供其他程序使用。
    举个例子
    if(pos<=0)
    {
    	exit(-1);//以状态值-1来结束程序,代表程序异常(提前)结束了
    }
    

    这是个比较激烈的方法,另一个方式,就是抛出异常(exception),表示一个自定义函数收到了错误的位置值,这个在第七章会讨论到

    • 参数列表里有个&变量,其中&代表引用。
    • 如果想知道某个数据类型的最小/最大值,标准库中的numeric_limits class会帮到你
      eg.
    #include<limits>
    int max_int=numeric_limits<int>::max();//查询int型的最大值(可表示数)
    double min)dbl=numeric_limits<double>::min();//查询double型的最小值(可表示数)
    

    格式就这么写,记下来即可!

    • 在函数声明中,你可以**选择不写参数列表里参数的名字,但参数类型你必须写!因为参数名称只有在函数内使用参数时才是有必要的,也就是函数定义中你得写参数列表里参数的名字了。**函数声明的时候尽量不要写参数名字啦(如果程序是比较小的程序)
    • 如果自定义函数的函数体的最后一条语句不是return,那么最后一条语句之后便是该函数的隐式退出点,也就是默认从函数体的最后一条语句后退出该自定义函数,所以你得判别下那个隐式退出点是不是会有在函数体最后一条语句之后的这个情况(即自定义函数的返回类型是不是void,若不是,你得在最后一条语句后加个return 返回的变量,要不然程序报错!若是void返回类型(不需要返回任何值),则不需要加return。)
    展开全文
  • 提高代码质量:如何编写函数  作者:狼狼的蓝胖子(@狼狼的蓝胖子) 2016-03-12 iOS开发 函数是实现程序功能的最基本单位,每一个程序都是由一个个最基本的函数构成的。写好一个函数是提高程序代码质量最关键...

    提高代码质量:如何编写函数 

    作者:狼狼的蓝胖子(@狼狼的蓝胖子)
    2016-03-12 iOS开发

    函数是实现程序功能的最基本单位,每一个程序都是由一个个最基本的函数构成的。写好一个函数是提高程序代码质量最关键的一步。本文就函数的编写,从函数命名,代码分布,技巧等方面入手,谈谈如何写好一个可读性高、易维护,易测试的函数。


    命名


    首先从命名说起,命名是提高可读性的第一步。如何为变量和函数命名一直是开发者心中的痛点之一,对于母语非英语的我们来说,更是难上加难。下面我来说说如何为函数命名的一些想法和感受:


    采用统一的命名规则


    在谈及如何为函数取一个准确而优雅的名字之前,首先最重要的是要有统一的命名规则。这是提高代码可读性的最基础的准则。

    帕斯卡命名法和驼峰命名法是目前比较流行的两种规则,不同语言采用的规则可能不一样,但是要记住一点:保持团队和个人风格一致。


    1、帕斯卡命名法

    帕斯卡命名法简单地说就是:多个单词组成一个名称时,每个单词的首字母大写。比如:


    publicvoidSendMessage();

    publicvoidCalculatePrice();


    在C#中,这种命名法常用于类、属性,函数等等,在JS中,构造函数也推荐采用这种方式命名。


    2、驼峰命名法


    驼峰命名法和帕斯卡命名法很类似,多个单词组成一个名称时,第一个单词全部小写,后面单词首字母大写。比如:


    varsendMessage = function(){};

    varcalculatePrice = function(){};


    驼峰命名法一般用于字段、局部变量、函数参数等等。在JS中,函数也常用此方法命名。


    采用哪种命名规则并不绝对,最重要的是要遵守团队约定,语言规范。


    尽可能完整地描述函数所做的所有事情


    有的开发者可能觉得相较于长函数名来说,短函数名看起来可能更简洁,看起来也更舒服。但是通常来说,函数名称越短其描述的意思越抽象。函数使用者对函数的第一印象就是函数名称,进而了解函数的功能,我们应该尽可能地描述到函数所做的所有事情,防止使用者不知道或误解造成潜在的错误。


    举个例子,假设我们做一个添加评论的功能,添加完毕后并返回评论总数量,如何命名比较合适呢?


    // 描述不够完整的函数名

    varcount = functionaddComment(){};

     

    // 描述完整的函数名

    varcount = functionaddCommentAndReturnCount(){};


    这只是简单的一个例子,实际开发中可能会遇到得更多复杂的情况,单一职责原则是我们开发函数要遵守的准则,但是有时候无法做到函数单一职责时,请记得函数名应该尽可能地描述所有事情。当你无法命名一个函数时,应该分析一下,这个函数的编写是否科学,有什么办法可以去优化它。


    采用准确的描述动词


    这一点对母语非英语的开发者来说应该是比较难的一点,想要提高这方面的能力,最主要的还是要提高词汇量,多阅读优秀代码积累经验。


    这里简单说说我自己的一些感想和看法:


    1、不要采用太抽象广泛的单词


    很多开发人员会采用一个比较宽泛的动词来为函数命名,最典型的一个例子就是get这个单词。我们平时开发中经常会通过各种不同的方式拿到数据,但是每一种方式都用get就有点太抽象了。具体如何命名,要具体分析:


    (1)简单的返回数据


    Person.prototype.getFullName = function(){

        returnthis.firstName = this.lastName;

    }


    (2)从远程获取数据


    varfetchPersons = function(){

        ...

        $.ajax({

        })

    }


    (3)从本地存储加载数据


    var loadPersons = function () {};


    (4)通过计算获取数据


    var calculateTotal = function () {};


    (5)从数组中查找数据


    var findSth = function (arr) {};


    (6)从一些数据生成或得到


    varcreateSth = function(data){};

    varbuildSth = function(data){};

    varparseSth = function(data){};


    这是一个简单的例子,我们平时开发中遇到的情况肯定会复杂得多,关键还是靠单词的积累,多阅读优秀源码


    下面是整理的一些常用的对仗词,大家可以参考使用


    add/remove        increment/decrement      open/close

    begin/end            insert/delete                      show/hide

    create/destory    lock/unlock                        source/target

    first/last              min/max                            star/stop

    get/put                next/previous                    up/down    

    get/set                old/new


    根据不同项目和需求制定好命名规则


    这一点也是很重要的,尤其是在团队合作中,不同的项目和需求可能导致的不同的命名规则。


    比如我们通常采用的命名规则是动宾结构,也就是动词在前,名词灾后。但是有一些项目,比如数据接口等项目中,有的团队会采用名字在前,动词在后的形式,例如:


    publicstaticProduct[]ProductsGet(){};

    publicstaticProduct[]ProductsDel(){};

    publicstaticCustomer[]CustomerDel(){};

    publicstaticCustomer[]CustomerDel(){};


    这种的好处是看到前面的名词,比如ProductsGet,就能很快的知道这是产品相关的数据接口。


    当然这个并不是绝对的,关键还是要团队共同制定和遵守同一套命名规则。


    函数参数


    函数使用者在调用函数时,必须严格遵守函数定义的参数,这对函数的易用性,可测试性等方面都是至关重要的。下面我从几个方面来谈谈关于如何优化好函数参数的一些想法。


    参数数量


    毫无疑问,函数参数越多,函数的易用性就越差,因为使用者需要严格眼中参数列表依次输入参数,如果某个参数输错,将导致不可意料的结果。

    但是,函数参数就一定越少越好吗?我们来看看下面的例子:


    varcount = 0;

    varunitPrice = 1.5;

    ....

    ...

    varcalculatePrice = function(){

        returncount * unitPrice;

    }


    在这个例子中,我们通过calculatePrice这个函数来计算价格,函数不接收任何参数,直接通过两个全局变量unitPrice和count进行计算。这种函数的定义对使用者来说非常方便,直接调用即可,不用输入任何参数。但是这里可能会有潜在的bug:全局变量可能在其他地方被修改成其他值了,难以进行单元测试等等问题。所以,这个函数可以传入数量和价格信息:


    varcalculatePrice = function(count,unitPrice){

        returncount * unitPrice;

    }


    这种方式下,函数使用者在使用时,要传入参数进行调用,避免了全局变量可能存在的问题。另外也降低了耦合,提高了可测试性,在测试的时候就不必依赖于全局变量。


    当然,在保证函数不依赖于全局变量和测试性的情况下,函数参数还是越少越好。《代码大全》中提出将函数的参数限制在7个以内,这个可以作为我们的参考。

    有的时候,我们不可避免地要使用超过10个以上函数,在这中情况下,我们可以考虑将类似的参数构造成一个类,我们来看看一个典型的例子。

    我相信大家平时一定做过这样的功能,列表筛选,其中涉及到各种条件的筛选,排序,分页等等功能,如果将参数一个一个地列出来必定会很长,例如:


    var filterHotel = function (city, checkIn, checkOut, price, star, position, wifi, meal, sort, pageIndex) {}


    这是一个筛选酒店的函数,其中的参数分别是城市,入住和退房时间,价格,星级,位置,是否有wifi,是否有早餐,排序,页码等等,实际的情况可能会更多。在这种参数特别多的情况下,我们可以考虑将一些相似的参数提取成类出来:


    functionDatePlace(city,checkIn,checkOut){

        this.city = city;

        this.checkIn = checkIn;

        this.checkOut = checkOut

    }

     

    functionHotelFeature(price,star,position,wifi,meal){

        this.price = price;

        this.star = star;

        this.position = position;

        this.wifi = wifi;

        this.meal = meal;

    }

     

    varfilterHotel = function(datePlce,hotelFeature,sort,pageIndex){};


    将多个参数提取成对象了,虽然对象数量增多了,但是函数参数更清晰了,调用起来也更方便了。


    尽量不要使用bool类型作为参数


    有的时候,我们会写出使用bool作为参数的情况,比如:


    vargetProduct = function(finished){

        if(finished){

        }

        else{

        }

    }

     

    // 调用

    getProduct(true);


    如果没有注释,使用者看到这样的代码:getProduct(true),他肯定搞不清楚true是代表什么意思,还要去查看函数定义才能明白这个函数是如何使用的。这就意味着这个函数不够清晰,就应该考虑去优化它。通常有两种方式去优化它:


    (1)将函数一分为二,分成两个函数getFinishedProduct和getUnFinishedProduct

    (2)将bool转换成有意义的枚举getProduct(ProductStatus)


    不要修改输入参数


    如果输入参数在函数内被修改了,很有可能造成潜在的bug,而且使用者不知道调用函数后居然会修改函数参数。


    正确使用输入参数的做法应该是只传入参数用于函数调用。


    如果不可避免地要修改,一定要在注释中说明。


    尽量不要使用输出参数


    使用输出参数说明这个函数不只做了一件事情,而且使用者使用的时候可能还会感到困惑。正确的方式应该是分解函数,让函数只做一件事。


    编写函数体


    函数体就是实现函数功能的整个逻辑,是一个函数最关键的地方。下面我谈谈关于函数代码编写的一些个人想法。


    相关操作放在一起


    有的时候,我们会在一个函数内进行一系列的操作来完成一个功能,比如:


    varcalculateTotalPrice = function()  {

        varroomCount = getRoomCount();

        varmealCount = getMealCount();

     

        varroomPrice = getRoomPrice(roomCount);

        varmealPrice = getMealPrice(mealCount);

     

        returnroomPrice + mealPrice;

    }


    这段代码计算了房间价格和早餐价格,然后将两者相加返回总价格。


    这段代码乍一看,没有什么问题,但是我们分析代码,我们先是分别获取了房间数量和早餐数量,然后再通过房间数量和早餐数量分别计算两者的价格。这种情况下,房间数量和计算房间价格的代码分散在了两个位置,早餐价格的计算也是分散到了两个位置。也就是两部分相关的代码分散在了各处,这样阅读起代码来逻辑会略显不通,代码组织不够好。我们应该让相关的语句和操作放在一起,也有利于重构代码。我们修改如下:


    varcalculateTotalPrice = function()  {

        varroomCount = getRoomCount();

        varroomPrice = getRoomPrice(roomCount);

     

        varmealCount = getMealCount();

        varmealPrice = getMealPrice(mealCount);

     

        returnroomPrice + mealPrice;

    }


    我们将相关的操作放在一起,这样代码看起来更清晰了,而且也更容易重构了。


    尽量减少代码嵌套


    我们平时写if,switch或for语句是常有的事儿,也一定写过多层if或for语句嵌套的情况,如果代码里的嵌套超过3层,阅读起来就会非常困难了。我们应该尽量避免代码嵌套多层,最好不要超过2层。下面我来说说我平时一些减少嵌套的技巧或方法。


    if语句嵌套的问题


    多层if语句嵌套是常有的事情,有什么好的方法可以减少嵌套呢?


    1、尽早终止函数或返回数据


    如果符合某个条件下可以直接终止函数,则应该将这个条件放在第一位。我们来看看下面的例子。


    if(condition1){

        if(condition2){

            if(condition3){

            }

            else{

                return;

            }    

        }

        else{

            return;

        }    

    }

    else{

        return;

    }


    这段代码中if语句嵌套了3层,看起来已经很复杂了,我们可以将最后面的return提取到最前面去。


    if(!condition1){

        return;

    }

    if(!condition2){

        return;

    }

    if(!condition3){

        return;

    }

    //doSth


    这段代码中,我们把condition1等于false的语句提取到前面,直接终止函数,将多层嵌套的if语句重构成只有一层if语句,代码也更清晰了。


    注意:一般情况下,我们写if语句会将条件为true的情况写在前面,这也比较符合我们的思维习惯。如果是多层嵌套的情况,应该优先减少if语句的嵌套


    2、不适用if语句或switch语句


    条件语句一般来说是不可避免的,有的时候,我们要判断很多条件就会写很多if-elseif语句,嵌套的话,就更加麻烦了。如果有一天增加了新需求,我们就要去增加一个if分支语句,这样不仅修改起来麻烦,而且容易出错。《代码大全》提出的表驱动法可以有效地解决if语句带来的问题。我们来看下面这个例子:


    if(condition == case1){

        return1;

    }

    elseif(condition == case2){

        return2;

    }

    elseif(condition == case3){

        return3;

    }

    elseif(condition == case4){

        return4;

    }


    这段代码分别依次判断了四种情况,如果再增加一种情况,我们就要再新增一个if分支,这样就可能造成潜在的问题,如何去优化这段代码呢?我们可以采用一个Map或Dictionary来将每一种情况和相应值一一对应。


    varmap = {

        "case1":1,

        "case2":2,

        "case3":3,

        "case4":4

    }

    returnmap[condition];


    通过map优化后,整个代码不仅更加简洁,修改起来也更方便而且不易出错了。


    当然,很多时候我们的条件判断语句并不是这么简单的,可能会涉及到复杂的逻辑运算,大家可以查看《代码大全》第18章,其中有详细的介绍。


    3、提取内层嵌套为一个函数进行调用


    多层嵌套的时候,我们还可以将内层嵌套提取到一个新的函数中,然后调用该函数,这样代码也就更清晰了。


    for循环嵌套优化


    for循环嵌套相比于if嵌套来说更加复杂,阅读起来会更麻烦,下面说说几点要注意的东西:


    1、最多只能两层for循环嵌套

    2、提取内层循环到新函数中

    3、多层循环时,不要简单地位索引变量命名为i,j,k等,容易造成混淆,要有具体的意思


    提取复杂逻辑,语义化


    有的时候,我们会写出一些比较复杂的逻辑,阅读代码的人看到后可能搞不清楚要做什么,这个时候,就应该提取出这段复杂的逻辑代码。


    if(age > 18 && gender == "man"){

        //doSth

    }


    这段代码表示当年龄大于18并且是男性的话,可以doSth,但是还是不够清晰,可以将其提取出来


    varcanDoSth = function(age,gender){

        returnage > 18 && gender == "man";

    }

    ...

    ...

    ...

    if(canDoSth(age,gender)){

        //doSth

    }


    虽说多了一个函数,但是代码更加清晰和语义化了。


    总结


    本文从函数命名,函数参数和函数的代码编写三个方面谈了关于如何编写好一个函数的感受和想法。文中提到了很多具体的情况,当然日常编码中肯定会遇到更多复杂的情况可能我暂时没有想到。我简单的归纳了几点:


    1、准确地对变量、函数命名

    2、不要有重复逻辑的代码

    3、函数的行数不要超过20行,这里的20行只是个大概,并不一定是这个数字

    4、减少嵌套

    我相信大家一定会很多关于这方面的经验,欢迎进行交流,共同提高代码质量。

    展开全文
  • 1.函数的定义 函数是组织好的,可以重复使用的,用来实现单一或者相关联功能的代码段 函数能提高应用的模块性,和代码的重复利用率 python提供了很多内建函数,比如print(),但用户也可以自己创建函数,被叫做自定义...
  • 编写函数或类时,还可为其编写测试。通过测试,可确定代码面对各种输入都能够按要求的那样工作。而且,在程序中添加新代码时,你也可以对其进行测试,确定它们不会破坏程序既有的行为! 第一部分:测试函数! 1.引入...
  • 本文就函数编写,从函数命名,代码分布,技巧等方面入手,谈谈如何写好一个可读性高、易维护,易测试的函数。 命名 首先从命名说起,命名是提高可读性的第一步。如何为变量和函数命名一直是开发者心中...
  • 本文就函数编写,从函数命名,代码分布,技巧等方面入手,谈谈如何写好一个可读性高、易维护,易测试的函数。 命名 首先从命名说起,命名是提高可读性的第一步。如何为变量和函数命名一直是开发者心中...
  • 2.1 如何编写函数   fibonacci函数:1 1 2 3 5 8 13 21...... 程序:编写一个函数 该函数返回fibonacci数列中由用户指定的某个位置的元素。例如用户可以询问fibonacci数列的第八个元素是什么? 我们的程序回答是21...
  • 【python】:python如何编写函数

    千次阅读 2016-03-20 20:51:23
    如果写博客是为了吹牛逼,那么将完全没有意义 ———-by 一个正在吹牛逼的人正文: 函数,我们首先得明白... 2,python函数如何编写及格式 这个问题很简单,我写一个python的函数模板即可def 函数名(函数变量,....):
  • 本文就函数编写,从函数命名,代码分布,技巧等方面入手,谈谈如何写好一个可读性高、易维护,易测试的函数。 命名 首先从命名说起,命名是提高可读性的第一步。如何为变量和函数命名一直是开发者心中...
  • 简介:有时候Sql Server的内置函数没有那么好用的时候,可以引用一下外部程序集,下面献下丑,做下添加外部程序集操作 1、准备程序,编译出一个MyCLR的DLL. &nbsp; public class CLRClass { [Microsoft.Sql...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,899
精华内容 4,359
关键字:

如何编写函数