导航

python学习笔记(5)

Posted on 2018-03-11 21:11  stumn  阅读(185)  评论(0)    收藏  举报

类,是类,是类,就是类

类的特点:封装, 继承, 多态

类的使用与性质方法汇总:

 1 class People(object):
 2     n = 123   #类变量
 3     def __init__(self, name, age, height):  #这里的self就是实例化的变量名(p1)
 4         #构造函数(在实例化时做一些类的初始化的工作)
 5         self.name = name
 6         self.age = age
 7         self.height = height
 8 
 9     def talk(self):
10         print("%s is talking......"%(self.name))
11 
12     def walk(self):
13         print("%s is walking......"%(self.name))
14 
15     def sleep(self):
16         print("%s is sleeping......"%(self.name))
17 
18 class Person(People):
19     def __init__(self, name, age, height, hobby): #定义子类自己的方法
20         # People.__init__(self, name, age, height)  #继承的两种方式
21         super(Person, self).__init__(name, age, height)
22         self.hobby = hobby
23 
24     def play(self):
25         print("%s likes to play %s." % (self.name, self.hobby))
26 
27     # def play(self):   #可以在子类里面直接定义方法
28     #     print("%s likes to play..."%(self.name))
29 
30 # p1 = Person('jenny', 22, 90, 'guitar')
31 # p1.name = 'jack'    #可以以实例化的变量名(p1)在类的外边调用类的方法
32 # p1.play()
33 # print(p1.n, People.n)  #可以通过变量名或者类的名字去调用类变量
34 # print(p1.name, People.name) #类名是不能调用实例变量,原因还是self就是p1
35 
36 Person.n = 666    #不会改变p1的n,只改变原类以及p2中的n
37 p1 = Person('jenny', 22, 90, 'guitar')
38 p1.n = 2223     #p1.n只能修改自身实例化的n,对于原类以及别的实例化对象都没有影响
39                 #(本质是在p1的内存里加入了n)
40 print(p1.n, Person.n)
41 
42 p2 = Person('danny', 14, 100, 'football')
43 print(p2.n)

 类变量的用途:共用的属性,节省开销;

class Person:
    cn = "中国"   #所有的实例共用一份
    def __init__(self, cn='china'):  #这样子的创建方式会在每个实例中开辟一块内存
        pass

析构函数:在实例释放,销毁的时候执行,通常用于做一些收尾工作,如关闭一些数据库链接以及打开的临时文件等;

class People(object):
    n = 123
    def __init__(self, name, age, height):
        self.name = name
        self.age = age
        self.height = height

    def __del__(self):   #析构函数
        print('del this file!')

    def talk(self):
        print("%s is talking......"%(self.name))

    def walk(self):
        print("%s is walking......"%(self.name))

    def sleep(self):
        print("%s is sleeping......"%(self.name))

class Person(People):
    def __init__(self, name, age, height, hobby):
        super(Person, self).__init__(name, age, height)
        self.hobby = hobby

    def play(self):
        print("%s likes to play %s." % (self.name, self.hobby))
第一种写法: p1
= Person('jenny', 22, 90, 'guitar') p1.play() p2 = Person('danny', 14, 100, 'football') p2.play() input: jenny likes to play guitar. danny likes to play football. del this file! del this file!
第二种写法: p1
= Person('jenny', 22, 90, 'guitar') p1.play() del p1 #删除实例化变量就调用析构函数 p2 = Person('danny', 14, 100, 'football') p2.play() input: jenny likes to play guitar. del this file! danny likes to play football. del this file!

私有方法&私有属性:

class People(object):
    def __init__(self, name, age, height):
        self.name = name
        self.age = age
        self.__height = height   #私有属性

    # def __del__(self):   #私有方法
    #     print('del this file!')

    def __talk(self):
        print("%s is talking......"%(self.name))

p1 = People('jenny', 22, 90)
# p1.__height = 100  #在这里应该属于新建了一个变量
# print(p1.__height)  #'People' object has no attribute '__height'

p1.__talk()  #'People' object has no attribute '__talk'        

多继承:

  2.7 经典类:深度优化;    新式类:广度优化;

  3.x 均是广度优化

#class People:  #经典类
class People(object):  #新式类
    def __init__(self, name, age, height):
        self.name = name
        self.age = age
        self.__height = height

    def __talk(self):
        print("%s is talking......"%(self.name))

    def walk(self):
        print("%s is walking......"%(self.name))

    def sleep(self):
        print("%s is sleeping......"%(self.name))

# class Relationship(object): #实例化时首先去父类中寻找构造方法,在调用该函数时早已经实例化变量
#     def make_friends(self, obj):
#         print("%s is making friends with %s"%(self.name, obj.name))

class Relationship(object): #实例化时首先去父类中寻找构造方法,在调用该函数时早已经实例化变量
    def __init__(self, n1, n2, n3):  #测试继承类的执行顺序
        print(self.name)
    def make_friends(self, obj):
        print("%s is making friends with %s"%(self.name, obj.name))

class Teacher(Relationship, People): #'Teacher' object has no attribute 'name',意味着从左到右执行
    # def __init__(self, name, age, height, hobby):   #存在时,在这里进行初始化
    #     super(Teacher, self).__init__(name, age, height)  #新式类的写法
    #     self.hobby = hobby

    def play(self):
        print("%s likes to play %s." % (self.name, self.hobby))

p1 = Teacher('jenny', 22, 90)
p2 = Teacher('danny', 14, 100)
p1.make_friends(p2)    #input:jenny is making friends with danny

另外一种类似多继承的形式——组合:

 1 class People(object):
 2     def __init__(self, name, age, height):
 3         self.name = name
 4         self.age = age
 5         self.height = height
 6 
 7 class Person(object):
 8     def __init__(self, job, sex):
 9         self.job = job
10         self.sex = sex
11 
12 person_obj = Person("teacher", "F")   #在这里实例化person类
13 
14 class Teacher(People):
15     def __init__(self, name, age, height, Person_obj, hobby):   #直接传入实例化的对象
16         People.__init__(self, name, age, height)
17         self.person = person_obj
18         self.hobby = hobby
19 
20 p1 = Teacher('jenny', 22, 90, "teacher", "football")
21 
22 print(p1.person.sex)   #F
23 print(p1.person.job)   #teacher

使用列表进一步说明继承:

class People(object):  #新式类
    def __init__(self, name, age, height):
        self.name = name
        self.age = age
        self.__height = height
        self.friends = []  #定义列表

class Relationship(object): #实例化时首先去父类中寻找构造方法,在调用该函数时早已经实例化变量
    def make_friends(self, obj):
        print("%s is making friends with %s"%(self.name, obj.name))
        self.friends.append(obj)  #添加实例化变量名

class Teacher(People, Relationship):
    def teach(self):
        print("%s likes to teach." %(self.name))

class Student(People, Relationship):
    def study(self):
        print("%s likes to study." %(self.name))

p1 = Teacher('jenny', 22, 90)
s1 = Student('danny', 14, 100)
p1.make_friends(s1)
print(p1.friends[0].name)  #danny ,相当于将s1存入到列表中

继承的完整程序分析:

class School(object):  #object是基类
    def __init__(self,name,addr):
        self.name = name
        self.addr = addr
        self.students = []
        self.staffs = []

    def enroll(self, stu_obj):
        print("为%s办理入学手续"%(stu_obj.name))
        self.students.append(stu_obj)

    def hire(self, staff_obj):
        print("%s入职"%(staff_obj.name))
        self.staffs.append(staff_obj)

class ShoolMate(object):
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def tell(self):
        pass

class Teacher(ShoolMate):
    def __init__(self,name,age,sex,salary,course):
        super(Teacher,self).__init__(name,age,sex)
        self.salary = salary
        self.course = course

    def tell(self):
        print('''--------info of [%s]----------
        Name:%s,
        Age:%s,
        Sex:%s,
        Salary:%s,
        Course:%s
        '''%(self.name,self.name,self.age,self.sex,self.salary,self.course))

    def teach(self):
        print("%s is teaching course [%s]"%(self.name,self.course))

class Student(ShoolMate):
    def __init__(self, name, age, sex, id, grade):
        super(Student, self).__init__(name, age, sex)
        self.id = id
        self.grade = grade

    def tell(self):
        print('''--------info of [%s]----------
        Name:%s,
        Age:%s,
        Sex:%s,
        ID:%s,
        Grade:%s
        ''' % (self.name, self.name, self.age, self.sex, self.id, self.grade))

    def teach(self):
        print("%s is learning in [%s]" % (self.name, self.grade))

school = School('xxx', 'earth')

t1 = Teacher("Jan", 34, 'F', 500000, 'math')
t2 = Teacher("Lisan", 55, 'M', 30000, 'English')

s1 = Student('Jenny', 12, 'F', 1001, 'grade_one')
s2 = Student('Danny', 13, 'M', 1002, 'grade_two')

# t1.tell()
# s1.tell()

school.enroll(s1)
school.enroll(s2)
school.hire(t1)

print(school.students[0].name)   #使用学校实例化变量名调用其中的student和staff
print(school.staffs[0].age)
View Code

关于类的多态特性分析:

多态:一种接口,多种实现(接口重用)

  python不直接支持多态,但可间接实现多态。

 1 class Animal():
 2     def __init__(self, name):
 3         self.name = name
 4 
 5     def talk(self):
 6         pass
 7 
 8     @staticmethod   #静态装饰器
 9     def animal_talk(obj):
10         obj.talk()
11 
12 class Cat(Animal):
13     def talk(self):
14         print("miao!")
15 
16 class Dog(Animal):
17     def talk(self):
18         print("wang!")
19 
20 
21 c = Cat('mimi')
22 d = Dog('wangwang')
23 Animal.animal_talk(c)   #间接实现了多态
24 Animal.animal_talk(d)

 附:静态方法, 类方法, 属性方法

静态方法:只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性;

class Human(object):
    def __init__(self, name):
        self.name = name

    @staticmethod   #静态方法
    def eat(self, food):
        print("%s is eating %s"%(self.name, food))

d = Human("xiaohuang")
d.eat(d, 'baozi')    #将实例化的变量传参进去

类方法:只能访问类变量, 不能访问实例变量

class Dog(object):
    name = 'dahuang'
    def __init__(self, name):
        self.name = name   #访问不了这里

    @classmethod  #类变量
    def eat(self, food):
        print("%s is eating %s"%(self.name, food))

d = Dog("xiaohuang")
d.eat('baozi')

属性方法:把一个方法变成一个静态属性

class Dog(object):
    name = 'dahuang'
    def __init__(self, name):
        self.name = name   #访问不了这里
        self.__food = None

    @property  #attribute
    def eat(self):
        print("%s is eating %s"%(self.name, self.__food))

    @eat.setter
    def eat(self, food):
        print("set to food:", food)
        self.__food = food

    @eat.deleter
    def eat(self):   
        del self.__food
        print("delete!")

d = Dog("xiaohuang")
d.eat  #xiaohuang is eating None
d.eat = 'baozi'   #set to food: baozi
d.eat  #xiaohuang is eating baozi

del d.eat  #这里是删除不了的,要想删除,调用@set.deleter