python培训Day7 随笔

今天先讲了random模块的使用

这个模块的作用其实就是随机生数字,它下面有是三个方法

import random
print random.random()  #默认方法是在0和1之间取一个随机带小数点的随机数
print random.randint(1,2) #在1和2之间随机取数字,可能是1也可能是2
print random.randrange(1,2) #在大于等于1切小于2的范围内取随机数,本例来说只能取到1这个值
0.240756960152
2
1

既然通过random模块可以取随机数,那么根据ascii码表的规则。从65以上到127的范围内就包含了从A-y的26个字母的大小写格式。通过chr()函数就可以将输入的数字转换成对应的ascii字符。

import random
num=random.randint(65,90)
print 'number is %d ASCII is %s' %(num,chr(num))
number is 85 ASCII is U

下个列子就死利用上述原理产生一个4位的包含大写字母和0-9随机数字的验证码

import random
#创建一个空字符串
checkcode=''
#循环4次
for i in range(4):
    #获取一个0-3之间的随机数
    current=random.randrange(0,4)
    #如果循环的次数与产生的随机数不相等
    if current != i:
        #就生成一个大写的英文字母
        temp=chr(random.randint(65,90))
    #如果循环次数与产生的随机数相等 
    else:
    #就产生一个0-9的随机数
        temp=random,range(0,9)
    #不管产生的是字母还是数字都追加到checkcode字符串中    
    checkcode+=str(temp)
#打印字符串    
print checkcode
EU31


面向对象

面向对象编程有三大特性 封装、继承、多态


封装的特性

封装其实就是将多个函数都需要用到的参数打包到类里面,赋值一次就可以给其他方法一直调用了。

例如下面两个函数,都需要要调用name来完成输出,需要重复给name赋值

def sayhi(name):
    print '%s say hi'%name
def drink(name):
    print '%s drink water'%name
sayhi('wgw')
drink('wgw')
wgw say hi
wgw drink water

如果我们使用类的封装特性,来实现就是如下的代码效果。只需要把name封装到类里面就好了。以后再调用类里面的方法就是实现打印输出,不需要反复赋值name了

class test_class():
    def __init__(self,name):
        self.name=name
    def sayhi(self):
        print '%s say hi'%self.name
    def drink(self):
        print '%s drink water'%self.name
obj=test_class('wgw')
obj.sayhi()
obj.drink()
wgw say hi
wgw drink water

上面只是简单的例子,如果我们有几十个函数,每个函数可能有像name一样的3-5个都要用到的参数。那样的话通过面向对象的方法,就会显得优势更加明显。代码更加简练了。


要调用被封装的name可以通过对象调用

class test_class():
    def __init__(self,name):
        self.name=name
    def sayhi(self):
        print '%s say hi'%self.name
    def drink(self):
        print '%s drink water'%self.name
obj=test_class('wgw') #类在实例化的时候会把obj赋值给self
print obj.name  #这个obj.name  其实就是self.name
wgw


python的封装条件 

a.多个方法共用一组变量,变相封装到对象中

b.通过模板创建多个对象  例如游戏




继承的特性

继承顾名思义,比如我们创建了上面的test_class()这个类。后来又创建了一个test_class2()类,新建的类里主要是是包含一些人物喜欢参加的运动。但是我们希望在这个类里输入name之后也可以通过sayhi()方法和大家打个招呼。这时候我们可以在新建的test_class()类里面再重写一遍sayhi()方法。当然这样是很low的作法。那么最高效的就是让test_class2继承wgwclass这类里面的方法。然后在wgwclass2里面就直接用父类的方法了。

class test_class():
    def __init__(self,name):
        self.name=name
    def sayhi(self):
        print '%s say hi'%self.name
    def drink(self):
        print '%s drink water'%self.name
class test_class2(test_class):  #继承父类的方法
    def __init__(self,name,age):
        test_class.__init__(self,name) #调用父类的__init__方法
        self.name=name
        self.age=age
    def basketball(self):
        print '%s %d years old like basketball'%(self.name,self.age)
obj=test_class2('lucy',18)
obj.sayhi()
obj.drink()
obj.basketball()
lucy say hi
lucy drink water
lucy 18 years old like basketball

通过结果看到新人物lucy不仅可以使用子类里的篮球方法,也可以继承使用父类里的sayhi()方法。


多继承

经典类 和 新式类

经典类和新式类在创建方式上所有不同

class old_class():  #旧式经典类
    pass
class new_class(object):  #新式类,主要是就是创建的时候要加个object
    pass

经典类的子类也是经典类    新式类的子类也是新式类

经典类和新式类在使用上没有多大的区别,主要区别就是在多继承时候,查找父类方法的侧重点不一样。例如经典类

class A: #父类是一个经典类
    def f(self):
        print 'This A'
class B(A):
    pass  #class B 里面没有f()方法
class C(A):
    def f(self):
        print 'This C'
class D(B,C): #class D 同时继承了B,C两个类
    pass
obj=D()
obj.f() #经典类是深度优先,class B里面没有就去B的父类A里面找
This A

新式类

class A(object): #父类是一个新式类
    def f(self):
        print 'This A'
class B(A):
    pass  #class B 里面没有f()方法
class C(A):
    def f(self):
        print 'This C'
class D(B,C): #class D 同时继承了B,C两个类
    pass
obj=D()
obj.f() #新式类是广度优先,class B里面没有就去同级别的class C()里面找
This C

272315068126604.jpg

但是要注意,所谓的深度优先和广度优先都是建立在class B 和 class C 都继承了class A的前提下的。如果class B没有继承 class A  那么当class B里没有f()方法时候,不管什么类都会去class C里面找。


多态的特性

老师说python1的多态功能相当差,跟没有差不多。所以基本没有实用价值。


以上就是面向对象的三大特性,老师说为了提升逼格有两点要注意:

第一、尽量使用新式类 这是以后的趋势

第二、别老说父类子类,听着就土。要改说基类、派生类。


类和对象在内存中如何保存

老师的说法是:类以及类中的方法在内存中只有一份,而根据类创建的每一个对象都在内存中需要存一份

425762-20150829133530437-321533636.jpg

听着是不是特别绕口?简单来说就就是,假设我们有一个叫person的类模版。那么这个模版就要占一份内存。下一步我们用person()创造了两个人物 wgw 和lucy 。那么每创建一个新人物就又单独占用一份内存空间。


类的成员

类的成员由三大部分组成:字段、方法、属性


字段

普通字段

我们创建类的时候,会使用__init__方法构造类。并且将参数赋值与self.xxx  其实这个self.xxx就类的字段,是类的普通字段

class wgw():
    def __init__(self,name):
        self.name=name  #定义一个普通字段
obj=wgw('test') #实例化
print obj.name  #通过对象+字段名  就可以访问普通字段
test

静态字段

应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段

静态字段是又一层的重用

class wgw():
    country='china'  #定义静态字段
    def __init__(self,name):
        self.name=name  
print wgw.country  #静态字段通过类名+地段名的当时调用
china

普通字段属于:对象

静态字段属于:类

425762-20150907094454965-329821364.jpg


方法  普通方法  类方法  静态方法

普通方法

在创建的时候必须要有一个self参数,被调用的时候把对象名称赋值给self

class wgw(object):
    def __init__(self):
        pass
    def saihi(self): #普通方法,由对象触发,可以加参数至少有一个self
        print 'hi everybody'

类方法

class wgw(object):
    def __init__(self):
        pass
    def saihi(self): #普通方法必须有个self
        print 'hi everybody'
    @classmethod #通过添加classmethod装饰器定义类方法
    def saybye(cls): #类方法,类方法触发的时候是把类自身赋值给cls传入方法,只能有一个cls 不能加其他参数
        print 'bye bye'
wgw.saybye()  #通过类名+方法名调用类方法

类方法相当于对方法进行了一个约束,一个方法只能有一个参数。调用的时候不需要在init里面定义字段和创建对象。节约内存开销

静态方法

class wgw(object):
    def __init__(self):
        pass
    def saihi(self): #普通方法,由对象触发,可以加参数至少有一个self
        print 'hi everybody'
    @classmethod #通过添加classmethod装饰器定义类方法
    def saybye(cls): #类方法,类方法触发的时候是把类自身赋值给cls传入方法,只能有一个cls 不能加其他参数
        print 'bye bye'
    @staticmethod  #通过添加staticmethod装饰器定义类方法
    def sayhello(name,age): #静态方法,由类触发。不需要加self 可以传入任意参数
        print 'hello'
wgw.sayhello('wgw',18) #通过类名+方法名调用静态方法

类里面使用静态方法,就相当于在类里创建个函数。因为不用在init里面定义字段,也不用创建对象了。节约内存开销


属性

属性的功能是把一个方法伪造成一个字段,对运行结果没有影响  和方法是一样的

属性也是方法的一种,只是被改造成一种字段形式被访问。

class wgw(object):
    def __init__(self,name):
        self.name=name
        pass
    @property   #通过添加property装饰器定义将方法定义成属性
    def goodboy(self): #属性只能有一个self参数
        return 'haha'
obj=wgw('lala')
print obj.name  #调用函数的字段
print obj.goodboy #调用设置为属性的goodboy()方法

从上面的调用方法上看,属性的确把一个方法伪装成了字段。并且调用方式都和字段一样。


类成员修饰符

类的成员上文都介绍过,包含字段、方法、属性

这些成员也有公有成员和私有成员

普通字段

class wgw(object):
    def __init__(self,name,age):
        self.name=name #公有字段
        self.age=age
    def sayhi(self):
        print '%s is %d years old'%(self.name,self.age)
obj=wgw('lala',18)
print obj.name #在类外面直接可以调用
obj.sayhi()
lala
lala is 18 years old

如果有人从外部对字段重新赋值,就会影响方法的运行结果

class wgw(object):
    def __init__(self,name,age):
        self.name=name #公有字段
        self.age=age
    def sayhi(self):
        print '%s is %d years old'%(self.name,self.age)
obj=wgw('lala',18)
obj.age=30 #在外部可以直接修改字段的值
obj.sayhi()
lala is 30 years old  #运行的结果被修改了

如果要杜绝这种情况的发生,可以将该字段设置为私有

class wgw(object):
    def __init__(self,name,age):
        self.__name=name #在字段名前面加两个下划线表示将该字段设置为私有
        self.age=age

设置为私有之后,该字段在就只能在类内部被调用,外部就访问不了了。而且这个类的派生类也不能再访问这个字段了。


方法和属性也都可以设置为私有的,同样是设置为私有之后就不能够被外部和派生类访问了。

最后附上一张python面向对象的全景图

wKioL1ZqIrqDlqSaAAa9LgjewOw871.jpg




本文出自 “霹雳豆包” 博客,谢绝转载!

你可能感兴趣的:(day,7)