Fork me on GitHub

Python笔记(五)

5-4 子类和继承
创建类:class subClass(Parent1[Parent1[Parent2,Parent3…]])
子类拥有父类的所有属性,并且可以自己添加自己的属性和方法

注释:父类P:数据max  方法:base() foo()
 class P(object):
     max = 10
     def base():
         print "in parent base"

     def foo():
         print "in parent foo max = %d",max
 注释:子类sub:max 方法:base(),foo()
 class sub(P):
     def foo1():
         print "in sub foo1 max = %d",max

 s = sub()
 s.foo1() 注释:使用的是sub类自己派生的方法
 s.base() 注释:使用的是sub中继承P类的base()方法

5-5 继承属性
class P(object):
“Parent Class”
max = 10
def init(self):
print “P init”
Class C(P):
pass
P.max = 10
print(C.max) 注释:C继承P类,所以C.max = 10
P.max = 100
print(C.max) 注释:当父类修改某个属性,子类也会改变 C.max = 100
可以使用ID命令看到他们的地址是一样的
C.max = 99
print(P.max) 注释:当修改子类的max属性后,子类的max属性覆盖了父类
P.max = 1000 的max属性,所以P.max不会改变,在修改P.max时,
print(C.max) C.max也不会受影响,可以使用ID看看地址变化。

pa = P() 注释:生成实例pa,调用P的init方法,输出 P init
pa.class 注释:pa所属类名:main.P
P.doc 注释:P类文档: Parent Class
P.bases 注释:P类父类:(object)

ch = C() 注释:C类没有init方法,因此继承P类的方法,
实例化过程输出 P init
ch.class 注释: ch的类名:main.C
C.doc 注释:doc是特殊的属性,子类不能继承父类的doc属性
C.bases 注释:C的父类是(main.P),base属性时父类的集合

5-6 重载
重载:相同的方法在不同类中不同的实现
class Person(object):
def init(self,name,age):
self.name = name
self.age = age
def eat(self):
print “Preson eat”

    class Student(Person):
        def __init__(self,name,age,grade)
            self.grade = grade

        def eat(self):
            print "Student eat"
Preson类,定义了人的属性,Student类继承了P类,重载了__init__、eat方法

s1 = Student("zhangsan",10,3)
s1.name = zhangsan
s1.age = 10
s1.grade = 3
s1.eat()为子类的方法

重新修改Student类:
        class Student(Person):
            def __init__(self,name,age,grade):
                Person.__init__(self,name,age)
                self.grade = grade
            def eat():
                print "Student eat"
如何在子类中调用父类的方法?
比如 s1 = Student("zhangsan",10,3)
    s1.eat()如何调用P类的eat()
    在子类的eat方法中添加一句  Persoon.eat(self) 就可以了

直接在子类中使用父类名调用父类的方法弊端:

class A (object):            
    def foo(self):
        print "in A foo"
class B (object):            
    def foo(self):
        print "in B foo"
class C (A):            
    def foo(self):
        A.foo(self)
 C继承A,并且调用了A的foo()的方法,如果C类的父类改为B类
 我们就需要修改C类的代码,如果方法多了那么就显得太麻烦了

 super:直接用类名调用父类:
class A (object):            
    def foo(self):
        print "in A foo"
class B (object):            
    def foo(self):
        print "in B foo"
class C (A):            
    def foo(self):
        super(C,self).foo()

通过super方式可以解决上面问题

多重继承:子类继承多个基类(父类)。多重继承问题:如何在父类中
找到子类中没有或者调用父类的方法。

Python类分为经典类和新式类
经典类是默认没有派生自某个基类:class A:
                                pass
经典类多重继承的时候采用从左到右,深度优先的匹配方法

新式类默认派生object基类:class A(object):
                            pass
新式类采用广度优先匹配法则

经典类是没有__MRO__和instance.mro()调用的,而新式类是有的

分析GR类方法的查找顺序:
class P1(object) :    
    def foo(self):
        print "in A foo"

class P2(object):
    def foo(self):
        pass
    def foo1(self):
        print "in P2 foo1"

class C1(P1, P2) :
    pass

class C2(P1, P2) :
    def foo1(self):
         print "C2 foo1"

class GR(C1,C2):
    pass
gr = GR()
gr.foo()
gr.foo1()

P1和P2的object去掉,经典类查找顺序:
GR.foo()查找过程:GR > C1 > P1
GR.FOO1()查找过程:GR > C1 > P1 > P2

新式类查找顺序:
GR.foo()查找过程:GR > C1 > C2 > P1
GR.foo1()查找过程:GR > C1 > C2
新式类有__mro__属性,可以知道查找顺序。

5-7 组合
组合:当一个类被定义后,就可以当作一个模块来使用,
可以把不同的类混合合并加入到其他类中,来增加功能和代码的重用性。
class Teachers(object):
def init(self,num):
self.num = num

class Students(object):
    def __init__(self,num):
        self.num = num

class School(objecct):
    def __init__(self,name,teachers,students):
        self.name = name
        注释:School自由身和Teachers与Students类组合而成
        self.teachers = teachers 
        selfstudents = students
分别创建Teachers和Students实例,然后创建一个学校实例
sch = School("清华",Teachers(1000),Students(200000))
sch.name
sch.techers.num 注释:访问学校老师数量
sch.students.num 注释:访问学校学生数量

5-8 类内建函数
issubclass(X,b) X是否是B的一个子类
isinstance(object,A) object是否是A的实例
hasattr()/getatter()/
setattr()/delattr() 得到和设置或者实例的属性
dir([object]) 得到类的属性
super() 根绝子类找到父类,类必须是新式类
vars([object]) 返回类属性,没有object返回locals()

类有很多特殊方法:
__strt__:字符输出
运算:__add__,__sub__,__mul__,__div__等
比较:__cmp__
构建自己的类:需求:给定一个浮点数,只保小数点后两位
                  实现加减乘除,支持print.
class F(object):
    def __init__(self,val):
        self.data = round(val,2)

    def __str__(self):
        return str(self.data)

    def __add__(self,other):
        return F(self.data + other.data)
f1 = F(10.202)
f2 = F(2.457)

私有化类属性:使用双下划线(__)开始的属性和方法不能通过类和实例直接访问
class F(object):
    def __init__(self,val):
        self.__data = val 注释:不能直接访问该属性

    def show_data(self):
        print self.__data
f = F(10)
f.__data 注释:访问失败,可以dir看一下类属性
f.show_data() 注释:可以正常访问

包装:对于一个存在的对象进行包装,增加新的,删除不要
    或者对已存在属性进行修改
授权:所有跟新功能有新的类来完成,已经存在的功能
    授权给默认属性,关键实现__getatter__()重载

class W(object):
    def __init__(self,obj):
        self.__data = obj

    def get(self):
        return self.__data

    def __str__():
        return str(self.__data)

    def __getattr__(self,attr):
        return getattr(self.__data,attr)

list1 = W([1,2,3])
list1 [1,2,3]
list1.index(2)[1]
list1.pop()
list1 [1,2]

##参考视频
奇猫的Python教学视频

作者 Luckyboy

Python笔记(四)

5-1 类和类属性
类语法: 关键字class + 类名称 + (object):
例如: class myclass(object):
“class document string”
pass
类属性:和被定义的类绑定,他和任何实列无关。
类数据属性:定义类的变量,可以在类创建后被使用,可以使用类中的方法进行更新。
例如: class C (object):
max = 100
print C.max
C.max = 1000
print C.max
5-2 类方法:可以通过类或它的实例来调用方法,方法的第一个参数是类对象不是实例对象
基本语法:class myclass(object):
def foo(self):
pass
方法调用过程:
class C(object):
max = 100
def set_max(x):
max = x
C c :实例化
c.set_max(1000) :C的实例调用set_max
C.set_max(999) :C类调用set_max
set_max(1001) :直接调用set_max

1.如果调用失败,可能因为python语法限制,方法必须绑定到一个实例上才能被调用
虽然调用失败,但是这个方法仍然是类的属性。
2.如果调用失败,可能因为全局命名空间中,没有这个函数,这个方法属于类。
类属性          说明
__name__        类名称
__doc__            类文档
__bases__        所有父类构成元组
__dict__        类所有属性
__module__        类所在模块
__class__        实例C对应的类

5-3 实例和实例属性
实例:根据类创建出来的一个对象。每个实例拥有相同的方法,但是数据可能不同。

实例初始化:当我们使用函数方式调用一个类,解释器使用类对象来实例化该对象,
并且设置该类的一些属性并返回该实例。

class myclass(object):
    "class document string"
    pass
c = myclass()

使用type可以确认c是否为类myclass的实例。

__init__构造方法(其实就是Java里面的构造器):
1.实例化对象的时候,第一步就是创建实例对象,如果创建成功并且存在
__init__()方法,那么就会调用该方法,否则就返回实例对象。
2.当我们实例化的时候,传入的参数第一个是实例本身被__init__接收。

例如: class student(object):
        注释:当初始化实例的时候调用该方法
        def __init__(self,name,age):
            self.name = name
            self.age = age
        注释:下面是两个实例化 s1 s2
       s1 = student('zhangsan',15)
       print s1.name,s1.age
       s2 = student('list',14)
       print s2.name,s2.age

__new__构造方法:
1.静态方法,实例化操作的时候生成,和__init__方法参数一样
__new__方法调用父类方法创建一个实例属性。

class student(object):
    注释:调用new方法产生并返回实例,然后调用实例的__init__方法
    def __new__(cls,name,age):
        print 'call __new__'
        return super(Person,cls)
        __new__(cls,name,age)
    注释:__init__方法中的self就是__new__方法产生的实例
    def __init__(self,name,age):
        print 'call __init__'
s1 = student('zhangsan',15)

__new__方法控制生成实例过程,属于类级别方法。主要是继承一些不可变
的class时,提供一个自定义之鞋类的实例化过程的途径。还有就是实现自定
义的metaclass.
__init__方法用于初始化实例初始化过程,始于实力级别方法

__del__析构方法:当对象引用为0的时候,才会调用,
如果我们显示定义__del__,我们必须调用父类的__del__方法
如果我们实例不引用为0,该对象的__del__不能被执行
class student(object):
    def __init(self,name,age):
        print 'call __init__'
    def __del__():
        print'call __del__'

s1 = student('zhangsan',15)
s2 = s1
s3 = s1
ss = student('lisi',14)
注释:student实例引用为0时,执行__del__方法,
     __del__方法只能被调用一次
del s1
del s2
del s3

实例属性:实例仅拥有数据属性,可以在实例创建后的任
意位置设置实例的属性。

class student(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
s1 = student('zhangsan',12)
if(s1.age > 11):
    注释:动态添加实例属性
    s1.height = 140
注释:动态属性陷阱,可能没有添加height属性
print s1.height

查看类的属性可以使用: dir()和 .__dict__

类属性和实例属性区别:
类属性仅与其被定义的类绑定,它和任何实例都无关
实例仅拥有数据属性,当一个实例被释放后,它的属性同时清除
类和实例都有自己的命名空间
当我们修改类的属性,实例也会受到影响。

class C(object):
    max = 10
    def __init__self(self,min):
        self.min = min

c1 = C(0)
c2 = C(1)
c1.min
c2.min
c1.max
c2. max
c1.max = 100
下面两者都为10
c2.max = ?
C.max = ?

静态方法和类方法:Python的静态犯法和类成员方法都可以被类或实例访问
可以使用函数修饰符staticmethod和classmethod实现静态方法和类方法

静态方法和类方法不同:
1.静态方法无需传入self参数,类方法需要传入代表本类的cls参数
2.静态方法无法访问实例变量和类变量,类也不能访问实例变量
但是可以访问类变量。

clss C(object):
    max = 10
    注释:静态方法
    @staticmethod
    def static_func():
        print 'call static_func'
    注释:类方法
    @classmethod
    def class_func(cls):
        print 'call class max = %d' % cls.max
C.static_func()
C.class_func()
c = C()
c.static_func()
c.class_func()

##参考视频
奇猫的Python教学视频

作者 Luckyboy

Python笔记(三)

##第四章
4-1 函数—定义/参数/返回值
函数:
函数是程序对逻辑进化结构化的一种编程方法,使用代码块对逻辑进行隔离,方便代码读写和修改。
Pyhton函数定义:
关键字def + 函数名 + (参数) + :
process..

    def foo():            def add(x,y):
        pass                return x + y

    python函数也是对象,函数也有相应的属性。
    dir(foo)

参数:
    形参/关键字参数/默认参数:
        形参:函数被调用,传入的参数必须和函数定义参数位置个数一致。

        关键字参数:关键字参数针对函数调用,这种调用方式可以让调用者使用参数名来区分参数,
        这种调用方式可以语序参数不按顺序,Python解释器会通过关键字来匹配参数的值。

        默认参数:默认参数声明默认值的参数,如果函数调用过程中,可以不传递该参数。

        形参/关键字参数                 默认参数:
        def _power(x,y):            def _power(x = 2, y = 1):
            return x*y                    return x*y

        _power(2,3) = 6                _power() = 2
        _power(y = 3,x = 2) = 6
    可变长度参数函数:
        可变长度参数函数声明中不能被显示命名,以为参数的数目在运行前或者在程序运行中是未知的。

        非关键字可变长度参数(元组):
            def func(formal_args,*vargs_args):
                pass
            form_args:函数被调用时,非可变参数赋值给函数声明中的局部变量。
            vargs_args:函数调用时,非关键参数按顺序插入到一个元组中,方便访问。

        关键字可变长度参数(字典):
            def func(formal_ars,**vargsed):pass
            formal_args:函数被调用时,非可变参数赋值给函数声明的局部变量。
            **vargsed:函数被调用时,不定数目的关键字参数,放到一个字典中,键为参数名,值为相对应的参数值。
    函数返回值:
        如果没有显示返回值,返回None
        如果函数返回值只有一个,那么返回该对象
        如果函数返回值有多个,那么返回一个元组
        返回值是序列或者字典,接收返回值方式不同,处理方式也不同。

    Python中,函数的声明和定义是一起的。

    def foo():
        bnar()

    def bar():
        print "in bar()"
    foo()

    首先声明foo()函数,然后声明了bar()函数,当我们调用foo()函数的时候,
    bar()函数已经存在,所以在foo()中可以调用bar成功。

4-2 函数—作用域/全局变量/局部变量
Python作用域:
local:比如function中的变量所在的作用域就是local
enclosing:某个function被嵌套后的上一层function的作用域
global:当前模块中的全局作用域
built-in:Python内置作用域

    python变量作用域:由变量在代码中定义位置决定
        x = 10
        def foo():
            print(x)
            x = 1
        foo()
    这个程序执行结果:报错。
    x = 1 和print(x)位置互换执行结果:1

    python中的if/else/elseif/try/for/while语句不会修改变量作用域。

变量查找顺序:本地 > 外部 > 全局 > 内置
    x = 10
    z = 10
    def foo():
        x = 5
        y = 1
        def bar():
            print("x = %d y = %d z = %d" % (x,y,z))
        return bar
    foo()()

    1.从本地变量查找(bar()的作用域)
    2.从外部作用域查找(foo()的作用域)
    3.从全局作用域查找(当前模块)

    在函数中修改全局变量 global x
    在内置函数中声明外部函数的局部变量,可以修改 nonlocal x

4-3 函数—函数式编程
函数式编程:
函数能够接受输入并产生输出
优点:
1.代码复用,编码效率更高,维护方便
2.易于测试和调试
3.模块化,代码更加容易组织
4.封装,多人开发中,保证自己代码不被别人修改
5.双方合作,为了保护核心代码,可以提供Python库和接口
4-4 函数—匿名函数和内置函数
匿名函数可以用lambda关键字来创建,一条完整的lambda语句是一个完整的表达式,
返回的值是一个可以调用的函数对象。
基本语法:lambda arg1,arg2…argN:process
实列:lambda x,y:return x + y
lambda : True
lambda:
1.调用lambda产生的函数对象和调用普通的函数对象类似
foo = lambda x,y: return x*y
bar = lambda *x : x
dic = lambda *
x:x
2.可以被当作参数传递给函数
def bar(foo):
return foo(2,3)
3.可以使用参数(形参、关键字参数、默认参数、不定长参数)
foo(2,3); foo(y=2,x=3); bar(1,2,3,4);dic(x=10,y=20)

lambda和函数对比:
    def add(x,y):        add = lambda x,y:x+y
        return x+y <==>                        <==>a = 1 + 1
    a = add(1,1)        a = add(1,1)
lambda表达式作为返回值:
    def foo(x):            
        return lambda y: x + y
    add = foo(10)
    sum = add(10)
    sum = 20
lambda和列表解析使用:
list_foo = [lambda x: x+n for n in range(10)]
list_foo返回的其实是列表函数也就是每一个元素是函数,
比如0号元素是lambda x:x
list_foo[0](10) = 10
list_foo[1](10) = 11
list_foo[8](10) = 18

分析列表解析过程:
    list_foo = [lambda x:x+n for n in range(10)]
    1.首先for循环引入了全局变量n
    2.产生一个函数列表:[lambda x: x+n]
    3.list_foo[0](10)->lambda:x+n -> 10+n(n是全局白能量,当列表解析完成后,n=9)
    所以这个列表所有函数都等于:
        def foo(x):return x+n
修改列表解析:
    list_foo = [lambda x,n=n:x+n for in range(10)]
    结果:
    list_foo[0](10) = 10
    list_foo[1](10) = 11

    函数列表内容:
    lambda 创建函数的时候引入了默认参数n=n,左边这个n是参数,是函数中的局部变量,
    右边n是列表解析过程中的实际值。
了解函数的map(function,sequence[,sequence,...]):
          reduce(function,sqeuence[,initial]):
          filter(function or None,sequence):
偏函数:讲函数某个参数固定,并且返回一个新的函数
    from functools import partial
        语法:partial(func,*args,**keywords)
    偏函数示例:
        讲字符串转化整数(16进制):int("256",16)
        使用偏函数:int16 = partial(int,base=16)
        int16('256')=>转化为10进制的
    partical实质创建并返回一个新的函数:
        def int16(x):
            return int(x,16)

4-5 函数—函数闭包/装饰器/生成器
闭包:在内部函数中,对外部作用域的变量进行引用,那么这个函数就是闭包。
示例:
def bar(base):
def in_bar(offset):
return base +offset
return in_bar
in_bar()函数引入了外部变量base,使用in_bar()函数就是闭包,当我们调用bar()的时候
返回给我们in_bar()函数,这个in_bar函数就是一个闭包
当我们调用bar(),传入base值,就是外部作用域变量

闭包的作用:
    提供数据封装,我们传给闭包一个属性,闭包给我们提供一个调用接口,
    代码复用,简化代码。

装饰器:
    是一个包装函数的函数,返回一个修改后的函数对象,把函数重新赋值,
    返回给原来的标识符,并丧失对原始函数对象的访问。
装饰器基本语法:
    @deco(deco_args)        #deco返回值为函数的函数
    def func(func_args):    #func有参或者无参
        pass
    实际结果:func = deco(func)
多重装饰器:deco1和deco2都是
          @deco1
          @deco2
          def func(arg):
                  pass
    其实就是:func = deco1(deco2(func))
这里是理解的难点,举一个示例。
def deco(func):                  def deco(func):
    print("in deco()")              print("in deco()")
    func()            使用装饰器     return func
                               @deco
def bar():            ---》 》 》        def bar():
    print("in bar")                    print("in bar")

deco(bar)                       bar()
前者并没有装饰效果,因为直接返回了func。

装饰器修改一个函数:
    def deco(func):
        print("in deco()")
        def foo():
            print("befor call func()")
            func()
            print("after call func()")
        return foo

    print("befor deco bar")
    @deco
    def bar():
        print("in bar")
    print("after call bar")

    bar()
上述代码执行过程:
    装饰器把foo函数返回给bar这个名字,deco的参数func是外部变量,foo调用func的时候
    其实是原来的bar函数,foo函数也就是一个闭包。当我们在调用bar函数的时候,
    类似于原来调用deco(bar)(),
    deco中的foo前面代码只执行一次,因为foo前面代码是外部作用域。

带参数的装饰器在调用的时候需要传入参数。本质上没差异

生成器:
    一个函数,函数的参数都会保存,当他返回时会记录代码执行到该函数位置。
    再次调用生成器函数会直接跳转之前位置,而且上次调用的所有局部变量不变。

python生成器:
    是一个带yield关键字的函数,yield能够返回给调用者一个结果,并且暂时执行,
    当调用者使用next()再次调用的时候,他会从yield后面语句继续执行。
python生成器语法: def gen():yield
示例and分析过程:
def generators():        gen = generators(): 结果:
    yield         >>>    gen.next()            None
    yield 10            gen.next()            10
    yield 20            gen.next()            20
                        gen.next()            StopIteration
    第一次调用:记录当前代码执行位置并返回None
    第二次调用:从上一次记录的位置开始执行,记录当前位置,返回10
    第三次调用:从上一次记录的位置开始记录当前位置,返回20
    第四次调用:没值了所以会报一个异常。

生成器使用:找出给定范围内的偶数
    def gen_even(max):
        n = 0
        whlie(n < max):
                if(n % 2 == 0):
                    yield n
                n++

    even = gen_even(100)
    even.next()...(这里可以用循环语句输出)

##参考视频
奇猫的Python教学视频

作者 Luckyboy

Python笔记(二)

##第三章
3-1逻辑结构与控制 if/else/elif
if控制语句:
组成:关键字if、逻辑表达式、逻辑代码
逻辑表达式的结果为:True/False
True:不为空或者0的变量(数组、序列、字典)
False:0、False、None、空的变量(序列、字典)

if(逻辑表达式):
    代码

特殊的: 表达式                          if语句
         函数    def test():            if(bool((test()-1)):
                     return False        print("Test return Flase")
else语句:
    和if语句搭配使用,if和else是一对一的关系。当if(Flase)的时候执行else。
if(else):
    do_yes
else:
    do_no


elif语句:
    检查多个表达式是否为真,并且有对应的代码。
    if(表达式1):
        true1_语句
    elif(表达式2):
        true2_语句
    elif(表达式3):
        true3_语句
    else:
        Flase1_语句

elif和if的嵌套:
    if嵌套是指if中含有if

        if(表达式1):
            if(表达式2):
                true_2语句
        else:
            expr1_false_suite

3-2逻辑控制—While语句
while循环语句:
代码块中会一直执行,知道条件不满足了,结束语句。
while循环语句分为:有限循环和无限循环
while循环语句语法:
while expression:
do_same_task

while和else语句:
    只有当while循环正常执行完时才会执行else语句
        while和else的配合使用
        i = 0
        while(i < 10):
            print(i)
            i += 1
        else:
            print("when i = %d,over" % i)

break语句:
    结束当前的循环,跳到下一个语句
    i = 0                        输出结果
    when(i < 10):                    0
        print(i)                    1
        i += 1                        2
        if(i == 5):                    3
            break                     4
    print("exec over i = %d" % i)    exec over i = 5

continue和pass:
    continue语句:
        结束当前的循环,忽略后面的语句,跳转到循环开始位置,然后根据表达式结果再决定是否循环

    i = 0                         输出结果
    while(i < 10):                    2
        i += 2                        4
        if(i % 2 != 0):                6
            continue                   8
        print(i)

    pass语句:
        空语句,不做任何操作
        作用:保持代码完整性,站位符或者创建站位程序
              一些异常处理,不采取任何措施。

3-3逻辑控制—for语句
for语句:
用来访问一个可迭代对象中的所有元素。并再遍历所有条目以后结束循环。
for语句语法:
for iter_val in iterable:
iter_val_del
循环索引依次从iterable取值,每循环一次就执行一次iter_val_del

序列:colors = ["green","red","yellow","blue","black"]
    使用序列项迭代:
        for color in colors:
            print(color)
    使用索引进行迭代:
        for index in range(len(colors)):
            print(colors[index])
    使用序列和索引进行迭代:
        for index, color in enumerate(colors):
            print(index,color)

遍历字典: dict1 = dict.fromkeys((1,2,3,4,5))
    for key in dict1:
        print(key,dict1[key])

访问迭代器:
    for循环访问迭代器的时候,调用next()方法得到一个条目,然后赋值给目标变量,当访问完后,会产生一个异常。
    for语句在内部会截取这个异常。
        for item in dict1.iteritems():
            print item
range方法:生成一个整数的list
    range(start = 0,stop,step = 1)其中step必须大于0

else语句也是当for语句正常执行完以后,才会触发else语句的内容。
for和else:
    for i in range(10):
        print(i)
    else:
        print("over i = %d" % i)

迭代器:
    迭代器是一个访问集合内元素的一种方式。迭代器对象从集合的第一个元素开始访问,
    知道所有的元素都被访问一遍以后结束。

    迭代器不能回退,只能往前进行迭代。

    优点:不要求你事先准备好整个迭代过程中所有的元素。
          提供统一访问集合的接口。
          迭代非序列集合(文件)
    迭代器迭代实质:
        迭代器有一个next()方法的对象,当循环访问迭代器的每个元素时,
        调用的是迭代器next()方法,当全部元素取出后,会引发一个StopIteration异常,告诉调用者,迭代完成。

    迭代器使用:
        myiter = iter("HellWord")
        while(True):
            print(myiter.next())
    判断对象是否可迭代:
        from collections import Iterable
        isinstance(obj,Iterable)
    单迭代对象:
        只要对象定的话,无论你是否再调用iter()对象,甚至是把这个对象赋值给其他变量名,
        你会发现这些变量指的是同一个地方
        map是单迭代对象
        m1 = range(10);m2 = map(abs,m1);m3 = iter(m2)
        next(m2)出不来,不知道是不是map的原因 map(函数,一个或多个序列)
        next(m3)

    for循环语句的实质:
        for in range(10):
            print(i)
        for循环语句会自动调用工厂函数iter()获得迭代器,然后调用next()方法,并且处理异常。

3-4逻辑控制—列表解析和生成器
列表解析:动态创建列表,在一个序列的值上应用一个任意表达式,把结果收集到一个新的列表中并返回。

基本语法:[expr for iter_var in iterable]
    mylist = [x+1 for in range(10)]
    [1,2,3,4,5,6,7,8,9,10]

扩展与法:[exper for iter_var in iterable if cond_expr]
mylist = [x+1 for x in range(10) if(x > 5)]
[7,8,9,10]

生成一个矩阵:
    myrange = [(x, y, z) for x in range(3) for y in range(3) for z in range(3) ] 

使用列表解析器统计枫树小于60的个数:
    [x for x in list1 if x < 60]
    把x满足条件的组成一个新的列表然后返回

将列表中小于60的分数替换为False
    [x >= 60 and x for x in list1]
    当x >= 60成立的时候返回X的值,作为列表成员
    当x >= 60不成立的时候返回Flase,作为列表的成员
给定一个字符串,得到每个字符串中单词及其对应的长度
    str = "welcome to python world"
    stuff = [[world,len(world)] ofr world in str1.split()]

生成器:
    表达式:它是列表解析器的一个阔转,分会一个生成器,生成器每次计算出一个条目,把这个条目产生出来。生成器使用延迟算法,他在内存上更为有效。

语法:
    (expr for iter in iterable if cond_expr)

创建:
    L1 = (val for val in range(10))

访问:L1.next()也可能是next(L1)

列表解析器和生成器表达式区别:
    列表解析器需要把所有条目创建出来。
    生成器表达式不需要把条目创建出来,每次计算的时候会把条目创建出来。

在这里需要提及到排序算法,排序算法这里就不作赘述:
以下为比较累排序:
    交换排序:冒泡排序、快速排序
    插入排序:简单插入排序、希尔排序
    选择排序:简单选择排序、堆排序
    归并排序:二路归并排序、多路归并排序

以下为非比较排序
    计数排序、桶排序、基数排序

##参考视频
奇猫的Python教学视频

作者 Luckyboy

Python笔记(一)

##第一章
1-1 Python开发环境
小要求:最好能够熟悉Linux基本操作,Linux是程序员的必备开发使用系统。

基于windows操作系统,安装开发环境。(不会的话可以上B站搜索相应的安装视频)
    Python官方网址(www.python.org)
    接着寻找相应的操作系统的Python版本。
    在选择的时候尽量把两个条件都选择上,减少你后期配置Path的环境变量的时间

    如果你想要集成开发环境,可以下载一个Pycharm
    官网下载地址:https://www.jetbrains.com/pycharm/download/
    安装地址:
    http://www.runoob.com/w3cnote/pycharm-windows-install.html
    具体的配置可以去B站搜搜看,这里我提供一个地址(也许会失效):
    https://www.bilibili.com/video/BV17b411e7M9?from=search&seid=4945926071261645762

    Eclips也可以配置Python环境,然后创建文件就可以了。奇猫的第一个视频会有详细步骤,如果遇到乱码,
    那么就是编码集出了问题。你需要调整一下你的编码集

1-2 变量与解释器内存管理

变量:
例如:a = 1   地址:0x1122  b = 2 地址:0x3344
     改 a 的值 a = 2 地址 0x3344  
     此时 a 和 b 的地址都是一样的,都是0x3344

解释器内存管理机制:

 先取一定数量的大小为256Kb的arenas空间,然后以链表的形式记录里面用过的空间。
 每一个arenas也是以链表的方式进行连接,每一个arenas中用过的数据都是以链表的方式连接,没用过的内容也是以链表方式连接。
 当你调用值时,那么先从已经记录过的地址去寻找,如果没有就新开辟一个地址。python解释器的垃圾回收机制是不会把你这个内存释放的,
 使用申请到一定量就不能申请了,只能从空闲的地址或arenas里面调用了。

1-3 python的基本语法
连接符”反斜杠”:
连接多个物理行,例如:
display = “ This is test func反斜杠
This is test func反斜杠
This is test func”

 引号:
     单引号、双引号、三引号标识字符:
     str = 'HelloWord'
     str = "HelloWord"
     str = """HelloWord"""
     str = '''HelloWord'''

注意事项:
    在输出字符串常量直接引用单引号(')和双引号(")的时候
        使用"的时候。字符串定义不难以"开始和结束
        使用'也是同样的道理

##第二章 Python的数据结构
2-1 数据结构——数字
数字的类型: int —> 整型 24字节
long —> 长整型(也许已经和int合并在一起了) 28字节
longa = 10L
float —> 浮点数 24字节
complex —> 复数 32字节
complexa = 4 + 1j
boolean —> 布尔值 24字节

        Python解释器对int、float、有最大限制,
        在赋值的时候python会识别值的类型

默认的数字转换优先级:
    complex > float > long >int

    优先级大转小的时候,会自动转化成大类型然后再进行运算。
    强制转换的时候需要加()
    特别说明complex:
    complex(x)  把x转换为实部x和虚部为零的复数
    complex(x,y) 把x和y转换为实数部分x和虚部y的复数

我们现实的数字和计算机的数字区别:
    计算机里面的数字都是以二进制补码的方式存在的。
        当数字为正数时:原码 = 反码 = 补码
        当数字为负数时:反码 = 原码符号位不变其他取反  补码 = 反码 + 1

        计算机内部的数字运算都是以补码的方式进行运算的。

    位运算:
        &(与) |(或) >>(右移) <<(左移) ~(取反) ^(异或)

    数字的标准函数:
        位运算的优先级 ~ > (<<) > (>>) > & > ^ > |

        标准函数:
            abs 绝对值 
            cmp(x,y) x > y:return 1| x = y:return 0 | x < y:return -1
            max(x,y,z....) 返回最大值
            min(x,y,z....) 返回最小值

    随机数:
        随机数使用时 导入包 import random

        1. random.random() 用于生成一个0 <= n < 1.0 的随机浮点数
        2.random.uniform(a,b) 用于生成一个指定指定范围的随机浮点数
        3.random.randint(a,b)用于生成一个指定指定范围的随机整数(a,b分别是上线)
        4.random.randrange([start],[top],[step]),从指定范围内,按照step递增的集合获取数。
        5.random.choice(sequence) 从序列中获取一个随机元素.
        6.random.shuffle(x[,random]) 用于将一个列表中的元素打乱
        例如:items = [1,2,3,4,5,6] random.shuffle(items)
        7.random.sample(sqeuence,k)从指定序列中随机获取一个指定长度的片断。

2-2数据结构——序列
序列包含了字符串(string)、列表(list)、元组类型(tuple)
三种类型
字符串和元组是固定长度,不能修改。列表可以插入、删除、替换。

    三者的索引值:
        正索引:0 ~ len - 1 和java、C语言一样
        负索引(python独有):-len ~ -1   -1代表最后一位。

基本操作和切片操作
    基本操作
        obj in seq :obj是否再seq中
        obj not in seq :obj是否不在seq中
        seq + seq1 : 连接序列seq和seq1,两者的序列要一致
        seq * N :序列重复相加N次
    切片操作
        [index] :取索引index出的元素
        [start:stop] :取所以start到stop的所有元素
        [start:stop:step:在索引start到stop之间,每隔step个取一个元素
序列的内建函数
    len :返回列表长度
    max/min(seq) :返回列表最大值/最小值
    sum(seq) : 返回seq的整形的总和
    reversed(seq) :以一个序列作为参数,返回一个逆序访问的迭代器 
    例如:a = reversed([1,2,3])
    zip(seq1,seq2...) :受任意多个(包括0个和1 个)序列作为参数,返回 一个tuple(元组)列表
    例如:zip("123","456")= [(1,4),(2,5),(3,6)]

2-3 字符串
字符串:单引号(‘)、双引号(“”)或者三引号(‘’’/“””)定义字符串,字符串的内容是不可变的。
创建和赋值操作:
str1 = “helloWorld”
str1 = str(10)
str1 = str([1,2,3,4,5])
str1 = str((1,2,3,4,5))
访问:
str1= “helloWorld”
print str1[1] = “e”
print str1[1:3] = “el”
print str1[1:9:3] = “eor”

    字符串的内容不可被修改
    例如 :str1[1] = 'a' 是错误的

格式化输出
    %c  把数值转化为字符  print("%c" % 65) ==》 A
    %d     把数字转为10进制数 print("%d" % 65)
    %s  把str()把参数转化为字符串 print("%s" % [1,2,3])
    %o %O 将数字转为8进制数 print("%o" % 65)
    %x %X 将数字转为16进制数 print("%x" % 65) 
    %f %F 将数字转为浮点 print("%f" % 65.1) 
    %% 输出% print("%%")
原始字符穿操作符(r/R)
    1.所有的字符串都是直接按照字面意思来使用,没有转义特殊或不能打印的字符
    2.print("\n")和print(r"\n")的不同
        "\n"是一个换行符
        r"\n"是字符\+n,实际值是转义字符\+n组成:"\\n"

    字符串如果想要修改或者截取,那就必须要新建一个字符串

    python字符串结尾不需要'\0'结尾i,只是你包含所定义的字符串的值
    python解释器来管理字符串的内存。

字符串的基本操作
     1.+   
     2.*   
     4.[::]  切片操作 
     5.cmp() 比较两个字符串大小  
     6.len()  字符串长度 
     7.max/min() 字符串中最大/最小元素
     8.str() 接收一个任意对象,生成一个str类型的对象
     9.unicode() 接收一个任意对象,生成一个unicode类型对象
     10.chr() 接受参数在0~255之间整数返回对应的字符
     11.unichar() 12.接受参数在0~0xffff之间整数返回相对应的unicode字符
     13.ord() 根据字符返回对应的ASCII

字符串的函数操作
    1.capitalize 字符串第一个字母大写
    2.count(str,x,y) 统计str在字符串索引x~y之间出现次数
    3.endswith(str,x,y) 判断字符串索引x~y之间是否以str结尾,是返回true,否返回false
    4.find(str,x,y) 查找字符串索引x~y之间是否存在str,是返回true,否返回false
    5.index(str,x,y) 同find,如果没找到str,报异常
    6.join(str1) 字符串本身和str1字符串合并
    7.replace(old,new,max) 把字符串中前max次出现的old替换为new,默认值为全部替换。
    8.upper() 返回小写转化为大写副本
    9.lower() 返回大写转化为小写副本

unicode字符串
    键盘输入值然后unicode会找到对应的字模,经过处理会把字模传给显卡,显卡输出到显示器

    unicode:是为了解决传统的字符编码方案的局限而产生的,它为每种 语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换。每个unicode字符占2个字节 

    unicode显示中国两个字的过程:
    先进行encoder(utf-8)编码成 xx\xx\xx\xx 找到对应的字模,然后和字符集GB2312、utf-8、GBK进行匹配,
    最后传入终端设置编码的格式。

unicode编码格式
    ASCII,ISO-8859-1, UTF-8, UTF-16
    UTF-8使用1~4个字节来表示其他语言的字符
    UTF-16使用2个字节来表示其他语言的字符

    和其他字符的转换:
    • str1 = u"一'  u'\u4e00' 
    • utf8= s.encode("utf8")  '\xe4\xb8\x80' 
    • utf8.decoder("utf8")  u'\u4e00' 
    • gbk=s.encode("gbk")   '\xd2\xbb' 
    • gbk.decoder("gbk")  u'\u4e00'

2-4 数据结构——列表
列表是序列式的数据类型,他可以通过索引或者切片操作来访问一个 或者多个连续的元素;列表元素可以改变

    定义初始化:
        mylist = [1,2,3,4,5]
        mylist = list("123456")
        mylist = list(('1','2','3'))
        mylist = range(10) 返回的值是0123456789以列表存在

    列表更新/修改:mylist[1] = 20

基本操作:
    1. []/[:]/[::] 切片操作 
    2. in/not in 成员关系 
    3. +  连接符 
    4. *  重复操作符 
    5. cmp() 比较两个列表 
    6. len()  返回列表元素个数 
    7. sorted() 列表正序
    8. reversed() 列表反序
    9. sum() 统计列表整数的和
    10. zip(seq1..) 根据seq1和其他列表参数生成一个元组列表(以最短的参数为个数)
    11. range([start,] stop[,step]) 根据start和stop指定范围以及step设置步长,生成一个序列

经常使用的函数:
    1. len(mylist) 列表长度
    2. mylist.append(x) 在列表最后添加元素
    3. mylist.insert(i,x) 在列表位置i处插入元素
    4. mylist.remove(x) 删除值为x元素并且长度-1
    5. mylist.reverse() 列表反序
    6. mylist.pop(i) 弹出并删除位置为i的元素
    7. mylist.sort() 对列表进行一个排序

2-5 数据结构——元组
定义:元组是python不可变的对象,如果你要更动这个元组,那么就需要新建一个元组,把数据存入其中

创建:
    tuple1 = ("what","is","python")
    tuple1 = tuple("abcd")
    tuple1 = () 空值
    tuple1 = ("abc",)

访问:
    tuple1 = ('a','b','c','d')
    print tuple1[10]
    print tuple1[0:3]
    print tuple[0:3:2]

更新、删除:
    tp1 = ('a','b')
    tp2 = ('c','d')
    tp3 = tp1 + tp2
    del tp1

函数:
    cmp(tp1,tp1) 比较元组
    len(tp1) 元组长度
    max/min(tp1) 从元组中返回最大值/最小值的项

不可变性:一旦定义就不能改变,除非你新建一个元组
可变:元组和列表的结合,元组不可变,但是元组里面的可变元素还是可以变的。
元组不可变的应用场景:如果我们把数据传给一个不了解的API接口,同时希望数据不能被改变,此时就可以使用元组

深拷贝和浅拷贝:等我了解清楚再来。

2-6 数据结构-字典
定义:字典是Python中的唯一的映射类型。映射类型对象里的哈希值(key)和指向的对象(value)是一对多的关系。
它是一个容器类型,能存储任意个数的Python对象,其中也包括其他容器类型。

直接赋值:
    dict = {}
    dict = {"ip":"127.0.0.1","port":80}

dict方法:传入一个元素是列表的元组作为参数
    dict3 = dict(("ip","127.0.0.1"),("port",90))
    dict3_1 = dict(x = 1,y = 2)
    dict3_2 = dict(**dict3_1)

哈希表:这个是根据key value而直接进行访问的数据结构
dict1            key            key(哈希值)        value
ip:127.0.0.1    ip       hash     134894231556       127.0.0.1
port:90            port  hash     4145156132846        90

字典的访问:dict1["port"]把key转化成hash值,接着找到对应的ID,根据ID找到对应的值。

字典的键值(key):
    不允许一个键值对应多个值,如果初始化或者更新过程中出现多个键 值,会存储最后一个对应值,其他的会被自动删除。 
    例如:dict1 = {"prot":80,"port":"8000"}
    dict1["port"] = 8000
    len(dict1) = 1

键值(key)是必须能转化成hash值的:
    Python解释器调用hash函数,根据字典中的键值来存储数据位置,如果键值改变,哈希函数会映射到不同地址来存储数据, 这样哈希函数就不能准确地存储或者获取相关数据。

    不可变的类型是可以hash # tuple、str、freezeset
    可变的类型是不可以hash # list、set

字典的基本操作:
    dict1 = {"ip":"127.0.0.1","port":80}

        访问:dict[key]
             dict1["ip"]
             for key in dict1:
                     print("dict[%s] = %s" % (key,dict1[key]))
        更新: dict1["port"] = "8000"

        删除:
            del(dict1["ip"])  删除key为ip的条目
            dict1.clear()    删除dict1中的所有条目
            del(dict1) 删除字典dict1
            dict1.pop("ip") 删除并返回键值为ip的条目
            dict1.popitem("ip")    删除并以元组形式返回字典第一个条目

字典标准函数:dict1 dict2
    str、list、tuple

    list(dict1) 返回dict1的键值从小到大排序的列表
    tuple(dcit1) 返回dict1的键值按键值从小到大排序的元组

    比较运算符cmp(dict1,dict2),先比较len,再比较各种的key,最后比较value。大于则返回1,反之返回-1,相等返回0

字典相关操作:
    dict1 = {'addr':{'ip':'127.0.0.1','port':80},'msg':18}    字典可以嵌套,value值可以是其他的
    len(dict1)    返回字典(key-value对)的长度
    'key' in dict1 dict1中是否含有'key'键值
    dict1['name'][ip]字典嵌套字典的key值索引
    dict1.has_key('key') 判断字典是否有key键值
    dict1.get(key,default) 如果dict1中有key,返回对应的值,否则返回默认值
    dict1.update(dict2) 合并dict1和dict2
    dict1.setdefault(key,value) 如果字典不存在key,则key默认值为value
    dict1.items() 返回由键和值组成元组列表
    dict1.keys() 返回key列表
    dict1.values() 返回value列表

##参考文献
奇猫的Python教学视频

作者 Luckyboy

Java基础笔记

第一章:JAVA的概述

第二章:基本的语法

第三章:数组

第四章:面向对象

(上)

(中)

(下)

第五章:异常处理

##参考文献

《JAVA编程思想》、尚硅谷教学视频(宋红康讲授)

作者:Luckyboy

  • © 2015-2020 John Doe
  • Powered by Hexo Theme Ayer
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信