文章

美丽优于丑陋,清楚优于含糊。简单优于复杂, 复杂优于繁琐。平坦优于曲折,宽松优于密集。

前言

我发现随着相隔时间越长,学习的热情就越低,在没有明确的目的时尤其如此。

到现在,我发现,我原本想用Python做的事情,其实Node也能做,虽然没有python做的那么好。

但相对应得我对Node也更熟悉...

然,就这么让开得头这么断了似乎也与我得初衷不符,所以,我再次捡起了这本python入门书。

将博客当笔记记得好处在这里就有所展示,纵使没有人阅读,也能监督自己不放弃....

这篇笔记主要记录内容,python得函数和模块相关,边看边记可能会比较零碎。

阅读笔记

函数

稍有常识得人都可以看出,如果有一个重复的部分,比如生成一个斐波那契数列或者别的什么计算...写成一个函数远比那些意大利面条状得一串串代码要好得多。而说到,编程里得函数,之所以要叫”函数“,想来也是如此,传入得参数就是自变量,而结果便是结果了...

python种表示函数的关键字为”def“下面以一个经典的素数判断为列:

def is_prime(num):
    if num == 1:
        return False
    for factor in range(2,num):
          if num%factor == 0:
              return False
          else:
              return True
# 打完发现..好像没什么好解释的..
# 素数除了1以外,只能被1和它本身整除的数
# 再来个生成斐波那契数列
def fibs(num):
        result = [0,1]
        for i in range(num-2):
            result.append(result[-2]+result[-1])
        return result;
# 实际打下来感觉,这个用缩进来表达作用域的做法..实在是不大习惯
# 额外函数有个文档字符串 _doc_ 这是函数的一个属性,可以当注释用

函数一定会返回...什么都不指定也会返回None...很好理解..

参数

关于参数的修改,如果是引用类型的值比如列表,在函数内部被修改后,函数外部的值也会随之变动。但如果本身是不可变的比如数字,就不会有这种联动。
在这里其实可以玩个花样比如,把数放入列表来实现参数的联动修改,但无论是从易用性还是语义来讲,接受修改后的返回值是更为明智的选择。

# 默认参数与更清晰的调用
# python函数在声明的时候可以给一个默认值,调用的时候也可以指定,这样可以不用管参数的顺序问题。
def hello(method='hello',object='wolrd'):
    print(method,object)
hello() # 输出hello wolrd
hello(object='chian',method='hi') # 输出hi china
# 客观来看,这种写法增加了代码输入量,但是使函数更加好懂且易用,权当写注释。
# 分配参数,python允许输入多数不确定的参数通过在定义时使用*来实现
def add(*params):
    i = 0
    reuslt = 0
    while i < len(params):
        result = result + params[i]
        i = i+1
    print(result)
add(1,2) # 3
add(1,2,3) # 6
# *params相当于传入的时候把参数打包成一个元组,它可以出现在参数的任何位置比如def daSomeThing(x,*params,y)
#使用两个**可以指定具体的值,不过内部都是元组就是了。就像def daSomeThing(x,**params,y) 调用的时候可以指定多数不确定的参数的key值

python函数由它的调用参数的多样性来讲,具备极大的易用性,这种设计思想其实也可以转到Js中,Js函数传入的参数为Object,定义在函数声明的括号里其实和这个效果差不多。
只是在Js中的话,我会选择声明在内部..看着更舒服一些。

作用域与递归

读完发现这块内容和Js如出一辙,作用域嵌套,作用域链,全局作用域,再熟悉不过,递归也是差不多的概念,也许这些东西大多数编程语言都一致吧。
简单来说,函数内缩进会生成新的作用域,这里你可以对全局的作用域也就是外部的变量进行调用和修改。
而你在函数里声明的变量外部是无法直接获取的。同时,函数内部还能在定义函数,一层层嵌套下去。
递归就是,函数在运行时调用自己本身实现,循环调用,只是,python在递归的时候,每次调用自身都会生成新的作用域,我认为这非常棒。
只是,Js的递归效率非常差,不知道python怎么样,不过我估计也好不到哪去..通常能避免就避免吧。

# 递归实现一个二分查找
def search(sequence,number,lower=0,upper=None):
    if upper is None:upper = len(sequence) -1
    if lower == upper:
        assert number == sequence[upper]
        return upper
    else:
        middle = (lower+upper) // 2
        if number > sequence[middle]:
            return search(sequence,number,middle+1,upper)
        else:
            return search(sequence,number,lower,middle)
list = [1,4,34,23,45,22,33,55,11,26]
list.sort()
search(list,23) # 7

在实际的生产生活中,也许我们会考虑用列表的index来查找,或者当你需要二分查找的时候去模块bisect中找。
这里只是剧烈,实际上,从目前所见,python似乎也很适合来进行函数式编程。

通过模块来管理函数

python的模块管理简单的令人发指。
只管import就是了,甚至格式要求都没。
觉得命名空间冲突可以

import somthing As method_1

只要其中一个函数

from somthing import fun_1
if __name__ == '__main__':
    fun()
# __name__是python的一个隐含变量,代表模块的名字
# 上面的操作意味着除非直接执行一个模块不然下面的代码不会执行
# 方便在一些函数模块里放入执行代码

需要注意的是引入自己写的模块需要提前告诉python的解析器这些模块在哪,以下以同级目录举例:

import moudle1 # 这是个自己写的module1.py,放在同级目录下 
# 报错:no moudle named 'module1'
#### 正确的做法
import sys
sys.path.append('./')
import module1 
# 一切正常且符合预期

抽象与多态与封装与浅谈面向对象编程

抽象

程序中所谓抽象通俗易懂的来说就是把一系列过程概括为一个过程,比如有一个功能需要先做A再做B再做C..
抽象后其实就叫“功能”..我们不关心A B C,只需要知道它有什么功能就是了。
而说到多态和封装,个人认为,它们则是实现抽象的手段。
比如说多态:这个功能不关心传进来的是一个字符串还是一个数字还是一个元组或者列表,它总是能返回合适的符合预期的结果这就是多态。
比如说封装:我不关心这个功能是怎么实现的,我知道它有什么结果,也就是所谓象外部隐藏不必要的细节。
很多功能库都属于这类,我不知道它是怎么实现的但我知道怎么用,这就是多态和封装的作用了。
再往下展开就是继承和类,换成Js就是prototyoe和构造函数。
这些结合起来我们就能实现很多花样,比如面向对象。
假如在Js里,面向对象,真的是面向“对象”..你完全可以用一个{},来做你功能的命名空间,在里面实现各种方法。
在python里则更传统一些,可以使用类也就是class来做这件事情。

# 创建一个类
class Person:
    def set_name(self,name):
        self.name=name
    def get_name(self,name):
        return self.name
    def greet(self):
        print("Hello,world! I'm{}.".format(selft.name))
# 调用
Tom = Person()
Tom.set_name('TomCat')
Apach = Person()
Aoach.set_name('httpd')
Tom.greet() # Hello,world I'm TomCat

继承与多态

说多态之前,我们也许应该看下继承,对于我来说,只学习过JavaScript基于原型链的继承,而且基本还没用过...基于这一点对继承进行理解,大概意思就是让一个类从另一个类把方法和属性“拿”过来以减少代码量。

class typeA:
    def init(self):
        self.someThing = []
class typeB(typeA):pass
# typeB是typeA的子类,拥有和typeA同样的init方法
# 可以通过issubClass(typeB,typeA) 来判断,typeB是否是typeA的子类
s = typeB()
# isinstance(s,typeB) 判断s是否是typeB的实例 

上面是一个简单而无用的列子,实际上typeB可以通过def一个init来覆盖(重写)typeA的init方法。
当我们调用这个经过子类重写的方法时,不同的子类对象会表现出不同的行为,这个就是多态(poly-morphism)。
实际上,继承可以有多重,然后就可以让你的类变得复杂而难以维护,这方面可以根据实际需求来取舍。

封装

说到封装,个人感觉和抽象的定义有些像..
重点就是隐藏各种细节,只向外部暴露(提供)简单的编程接口..
换句话说就是API战士只需要知道怎么调用,而不需要考虑怎么实现..
用JQuery来举例就是,我只需要知道$.get,$.post,或者高级点再知道个$.ajax是怎么调用的,而不需要知道xhr的全过程或者模型之类的东西....
或者无疑比前者要复杂一些,实际上,xhr模型我现在只能回忆起个大概,但是你让我用$.ajax去掉接口则是毫无压力的...

面向对象编程

之前,复习JavaScript的时候已经复习过一遍了...过多的内容也就不再赘述..随手一摘抄。

  • .将相关的东西放在一起,如果一个函数操作一个全局变量,最好将它们作为一个类的属性和方法
  • 不要让对象之间过于亲密,方法应只关心其所属实例的属性。
  • 慎用继承
  • 保持简单,一般而言应确保大多数方法能在30S内读完并理解。

    结语

    这篇笔记大概很早就开始打了,但是,中间由于工作和个人兴趣原因,间隔了很长很长的时间...再捡起来看的时候已经有种这是啥?这又是啥之感..不过还算了解了。关于类和继承,其实还能扩展,不过,感觉看了也记不住...等着在实践中学习吧...再加个错误处理,差不多我就能说基础语法学完...只是..现在写nodeJs写的正顺手,一时半会还真没有跑来写python的欲望...可能又会在相当长的时间,暂时搁置....

评论

This is just a placeholder img.