面向对象

1 类的定义和使用

2 对象的定义和使用

3 属性查找与绑定方法

4 继承与派生

5 组合

6 抽象类

7 多态和多态性

8 封装

9 绑定方法与非绑定方法

10 其它内置函数


 8.1 类的定义和使用

# 类体代码在类的定义阶段就会立刻执行
class Student:
    school='oldboy' #数据属性

    def learn(self): #函数属性
        print('is learning')

    def choose_course(self): #函数属性
        print('choose course')

print(Student)
print(Student.__dict__) #查看类属性

#查看
print(Student.school) #数据属性
print(Student.learn) #函数属性

#增加
Student.country='China'
print(Student.country)

#修改
Student.school='Oldboy'
print(Student.school)

#删除
del Student.country
print(Student.country)

print(Student.learn)
Student.learn('xxxxx')

8.2 对象的定义和使用

class Student:
    school='oldboy'

    #stu1,'李三炮','男',18
    def __init__(self,name,sex,age): #在调用类时会自动触发执行
        self.Name=name
        self.Sex=sex
        self.Age = age

    def learn(self):
        print('is learning')

    def choose_course(self):
        print('choose course')

#调用类的过程又称之为实例化:stu1=Student('李三炮','男',18)
#1、得到一个返回值,即对象,该对象是一个空对象stu1
#2、Student.__init__(stu1,'李三炮','男',18)

stu1=Student('李三炮','',18)
print(stu1.__dict__)
print(stu1.Name,stu1.Age,stu1.Sex)

stu2=Student('张铁蛋','',38)
stu3=Student('武大郎','',28)
print(stu2.__dict__)
print(stu3.__dict__)

print(stu1,stu2,stu3)
print(stu2.Name)

8.3 属性查找与绑定方法

x=1
class Student:
    school='oldboy'
    # Name='xxx'
    def __init__(self,name,sex,age): #在调用类时会自动触发执行
        self.Name = name
        self.Sex = sex
        self.Age = age

    def learn(self,x,y):
        print('%s is learning' %self.Name)
        print(x,y)

    def choose_course(self):
        print('choose course')

    def commit_hw():
        print('commit homework')

#1、查找一个对象的属性顺序是:先找对象自己的__dict__,再找类的__dict__
stu1=Student('李三炮','',18)
print(stu1.__dict__)

print(stu1.Name)
print(stu1.school)
print(stu1.x)

stu1=Student('李三炮','',18)
stu2=Student('张铁蛋','',38)
stu3=Student('武大郎','',28)

# 2、类的数据属性是所有对象共享,所有对象都指向同一个内存地址
stu1.school='xxx'
Student.school='Oldgirl'
print(Student.school,id(Student.school))
print(stu1.school,id(stu1.school))
print(stu2.school,id(stu2.school))
print(stu3.school,id(stu3.school))

# 3、类中定义的函数是绑定给对象使用:
# 3.1:不同对象就是不同绑定方法
# 3.2:绑定给谁,就应该由谁来调用,谁来调用就会把谁当做第一个参数传给对应的函数
print(Student.learn)
print(stu1.learn)
print(stu2.learn)
print(stu3.learn)

stu1.learn(1,2) #Student.learn(stu1,1,2)
stu2.learn(1,3)
stu3.learn(1,4)
print(Student.learn)

stu1.commit_hw()
class Garen:  #定义英雄盖伦的类,不同的玩家可以用它实例出自己英雄;
    camp='demacia' #所有玩家的英雄(盖伦)的阵营都是Demacia
    def __init__(self,nickname,life_value,aggresivity):
        self.nickname=nickname #为自己的盖伦起个别名
        self.life_value=life_value  #英雄都有自己的生命值
        self.aggresivity=aggresivity #英雄都有自己的攻击力
    def attack(self,enemy):  #普通攻击技能,enemy是敌人
        enemy.life_value-=self.aggresivity #根据自己的攻击力,攻击敌人就减掉敌人的生命值

class Riven: 
    camp = 'Noxus'所有玩家的英雄(锐雯)的阵营都是Noxus;

    def __init__(self, nickname, life_value, aggresivity):
        self.nickname = nickname
        self.life_value = life_value
        self.aggresivity = aggresivity

    def attack(self, enemy):
        enemy.life_value -= self.aggresivity

    def fire(self,enemy):
        enemy.life_value-=100

g1=Garen('草丛猥琐男',1000,100)
r1=Riven('猛男雯雯',200,500)

print(r1.life_value)
g1.attack(r1)
print(r1.life_value)
小练习

8.4 继承与派生

     http://www.cnblogs.com/snailgirl/p/8513785.html 

8.5 组合

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...

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

class Course:
    def __init__(self,name,period,price):
        self.name=name
        self.period=period
        self.price=price
    def tell_info(self):
        print('<%s %s %s>' %(self.name,self.period,self.price))

class Teacher(People):
    def __init__(self,name,age,sex,job_title):
        People.__init__(self,name,age,sex)
        self.job_title=job_title
        self.course=[]
        self.students=[]

class Student(People):
    def __init__(self,name,age,sex):
        People.__init__(self,name,age,sex)
        self.course=[]

egon=Teacher('egon',18,'male','沙河霸道金牌讲师')
s1=Student('牛榴弹',18,'female')

python=Course('python','3mons',3000.0)
linux=Course('python','3mons',3000.0)

#为老师egon和学生s1添加课程,组合
egon.course.append(python)
egon.course.append(linux)
s1.course.append(python)

#为老师egon添加学生s1,组合
egon.students.append(s1)

#使用
for obj in egon.course:
    obj.tell_info()

8.6 抽象类

import abc

class File(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def read(self):
        pass

    @abc.abstractmethod
    def write(self):
        pass

class Disk(File):
    def read(self):
        print('disk read')

    def write(self):
        print('disk write')

class Process(File):
    def read(self):
        print('Process read')

    def write(self):
        print('Process write')

d=Disk()
p=Process()

d.read()
d.write()

p.read()
p.write()

8.7 多态和多态性

8.7.1 多态

多态指的是一类事物有多种形态

动物有多种形态:人,狗,猪

import abc
class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
    @abc.abstractmethod
    def talk(self):
        pass

class People(Animal): #动物的形态之一:人
    def talk(self):
        print('say hello')

class Dog(Animal): #动物的形态之二:狗
    def talk(self):
        print('say wangwang')

class Pig(Animal): #动物的形态之三:猪
    def talk(self):
        print('say aoao')

8.7.2 多态性

多态性是指在不考虑实例类型的情况下使用实例

多态性分为静态多态性和动态多态性

  静态多态性:如任何类型都可以用运算符+进行运算

  动态多态性:如下

peo=People()
dog=Dog()
pig=Pig()

#peo、dog、pig都是动物,只要是动物肯定有talk方法
#于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
peo.talk()
dog.talk()
pig.talk()

#更进一步,我们可以定义一个统一的接口来使用
def func(obj):
    obj.talk()
>>> class Cat(Animal): #属于动物的另外一种形态:猫
...     def talk(self):
...         print('say miao')
... 
>>> def func(animal): #对于使用者来说,自己的代码根本无需改动
...     animal.talk()
... 
>>> cat1=Cat() #实例出一只猫
>>> func(cat1) #甚至连调用方式也无需改变,就能调用猫的talk功能
say miao

'''
这样我们新增了一个形态Cat,由Cat类产生的实例cat1,使用者可以在完全不需要修改自己代码的情况下。使用和人、狗、猪一样的方式调用cat1的talk方法,即func(cat1)
'''

鸭子类型

例1:利用标准库中定义的各种‘与文件类似’的对象,尽管这些对象的工作方式像文件,但他们没有继承内置文件对象的方法

#二者都像鸭子,二者看起来都像文件,因而就可以当文件一样去用
class TxtFile:
    def read(self):
        pass

    def write(self):
        pass

class DiskFile:
    def read(self):
        pass
    def write(self):
        pass

例2:其实大家一直在享受着多态性带来的好处,比如Python的序列类型有多种形态:字

符串,列表,元组,多态性体现如下

#str,list,tuple都是序列类型
s=str('hello')
l=list([1,2,3])
t=tuple((4,5,6))

#我们可以在不考虑三者类型的前提下使用s,l,t
s.__len__()
l.__len__()
t.__len__()

len(s)
len(l)
len(t)

8.8 封装

      http://www.cnblogs.com/snailgirl/p/8513810.html 

8.9 绑定方法与非绑定方法

#绑定方法:绑定给谁就应该由谁来调用,谁来调用就会把谁当做第一个参数自动传入
#非绑定方法:在类内部用staticmethod装饰的函数即非绑定方法,就是普通函数
import settings
import hashlib
import time

class MySQL:
    def __init__(self,host,port):
        self.host=host
        self.port=port

    def func(self):
        print('%s 说:你好啊我的天' %self.name)

    @classmethod
    def from_conf(cls):#classmehtod是给类用的,即绑定到类,类在使用时会将类本身当做参数传给类方法的第一个参数(即便是对象来调用也会将类当作第一个参数传入)
        return cls(settings.HOST,settings.PORT)

    @staticmethod
    def create_id(n): #statimethod不与类或对象绑定,谁都可以调用,没有自动传值效果
        m=hashlib.md5()
        m.update(str(time.clock()+n).encode('utf-8'))
        return m.hexdigest()

# conn=MySQL('127.0.0.1',3306)

conn=MySQL.from_conf()
# print(conn.host,conn.port)

print(MySQL.create_id(1))
print(conn.create_id(2))
import settings
class MySQL:
    def __init__(self,host,port):
        self.host=host
        self.port=port

    @staticmethod
    def from_conf():
        return MySQL(settings.HOST,settings.PORT)

# @classmethod #哪个类来调用,就将哪个类当做第一个参数传入
# def from_conf(cls):
#     return cls(settings.HOST,settings.PORT)

    def __str__(self):
        return '就不告诉你'

class Mariadb(MySQL):
    def __str__(self):
        return '<%s:%s>' %(self.host,self.port)

m=Mariadb.from_conf()
print(m) #我们的意图是想触发Mariadb.__str__,但是结果触发了MySQL.__str__的执行,打印就不告诉你:
classmethod与staticmethod的区别:

8.10 其它内置函数

       http://www.cnblogs.com/snailgirl/p/8513819.html 

原文地址:https://www.cnblogs.com/snailgirl/p/8513761.html