面向对象

类的语法:

class Animal(object):  #class是创建类的关键字  Animal是类名  object是新式类的写法
    def __init__(self,name): #初始化方法,也称构造方法,创建了类的实例时会调用该方法, self代表实例本身,谁调用类,self就是谁。name是属性,也成实例变量
        self.name = name   
    def talk(self):    #self在定义类的方法时必须有,虽然调用时不必传入参数
        print('animal [%s] is talking'%self.name)
a1 = Animal('dog')   #类的实例化 ,python会自动把a1变量赋值给self这个参数
a1.talk()
#1,实例化时会在内存里开辟一块空间指向 a1这个变量名
#2,调用Animal类并执行__init__(...)为了把name等属性跟刚开辟的a1关联起来,关联后就可以直接用a1.name 调用了
#3,所以这个__init__(…)方法里的,self.name = name,self.role = role的意思就是要把这几个值存到a1的内存空间里

类的实例化:把一个抽象的类通过实例化变为一个具体的对象

面向对象编程三个特点:封装,继承,多态

封装:把使用构造方法将内容封装到某个具体对象中,然后通过对象直接或者self间接获取被封装内容。

继承:在OOP程序设计中,定义一个class的时候,可以从某个现有的class继承,通过继承创建的新的class 称为 子类 或 派生类 ,被继承的class称为 基类、父类 或 超类。

例如:

class Animal(object):
    def talk(self):
        print('animal is talking')
class Dog(Animal):  #子类
    pass
class Cat(Animal):   #子类
    pass
d=Dog()
c=Cat()
d.talk()   #继承了父类的方法
c.talk()   #继承了父类的方法
得到
animal is talking
animal is talking

继承的时候,如果父类和子类都有相同方法,执行哪一个呢?

class Animal(object):
    def __init__(self):  
        self.func()
    def func(self):    
        print("Animal Class")
class Dog(Animal):    
    def func(self):   #与父类同名的方法func()
        print("Dog class")
d = Dog()    #实例化了子类
结果: 
Dog class

对象之间的交互:

'''
对象之间的交互
'''
class Animal:
    '''奥特曼和小怪兽都有的属性,名字,伤害值,生命值'''
    def __init__(self,name,damage,life_value):
        self.name = name
        self.damage = damage
        self.life_val = life_value
class People(Animal):
    '''人可以攻击小怪兽'''
    def attack(self,monster):
        monster.life_val -= self.damage
class Monster(Animal):
    '''小怪兽咬人'''
    def bite(self,people):
        people.life_val -= self.damage
p=People('奥特曼',30,2000)
m=Monster('小怪兽',20,1000)
print("奥特曼初始生命值",p.life_val)
m.bite(p)
m.bite(p)
print("奥特曼被咬了两口:",p.life_val)
print('--------------------------------')
print("小怪兽初始生命值",m.life_val)
p.attack(m)
print("小怪兽挨揍了之后生命值",m.life_val)

结果:
奥特曼初始生命值 2000
奥特曼被咬了两口: 1960
--------------------------------
小怪兽初始生命值 1000
小怪兽挨揍了之后生命值 970
class Monster:
    def __init__(self,name,damage,life_value):
        self.name = name
        self.damage = damage
        self.life_value = life_value
    def bite(self,person):
        '''怪兽咬人,人的生命值减少'''
        person.life_value -= self.damage
class People:
    def __init__(self,name,money,life_value,damage = 0):
        '''人的属性:名字,生命值,钱,战斗力为0'''
        self.damage = damage
        self.name = name
        self.life_value = life_value
        self.money = money
class Weapon:
    '''武器类:名字,价格,战斗力'''
    def __init__(self,name,value,damage):
        self.name = name
        self.value = value
        self.damage = damage
    def buyed_by(self,people):  #击中对方,对方生命值减少
        people.money -= self.value
        people.damage += self.damage
    def shooted(self,obj):    #击中对方,对方生命值,战斗力减少
        obj.life_value -= self.damage
        obj.damage -= 100
if __name__ == "__main__":
    p = People('正义者',1000,5,0)
    m = Monster('怪兽',100,5)
    w = Weapon('AK48',200,500)
    if p.money > w.value:
        print("正义者买了一把枪")
        w.buyed_by(p)
        p.weapon = w
    else:
        print("正义者还买不起武器,只能等死了...")
    print("怪兽生命值:%s,战斗力:%s"%(m.life_value,m.damage))
    p.weapon.shooted(m)
    print("正义者开枪了")
    print("怪兽生命值:%s,战斗力:%s" % (m.life_value, m.damage))

结果:
正义者买了一把枪
怪兽生命值:5,战斗力:100
正义者开枪了
怪兽生命值:-495,战斗力:0
一个小游戏

 继承和重写

class SchoolMember(object):   #父类
    def __init__(self,name,age):
        self.name = name
        self.age = age
class Student(SchoolMember):   #子类
    def __init__(self,name,age,grade):   #先重写
        super(Student,self).__init__(name,age)  #后继承  super关键字
        self.grade = grade
    def prt_name(self):
        print("student [%s]'s grade is [%s]"%(self.name,self.grade))
class Teacher(SchoolMember):   #子类
    def __init__(self,name,age,course):   #重写
        super(Teacher,self).__init__(name,age)  #继承
        self.course = course
    def Teach(self):
        print('Teacher %s is teaching [%s] now'%(self.name,self.course))
s=Student('lily',22,14)    #类的实例化
s.prt_name()    #调用方法
t=Teacher('alex',30,'python')    #类的实例化
t.Teach()

可以通过  issubclass(sub,super) 判断是否是继承关系

print(issubclass(Student,SchoolMember))

多态:实现接口的重用。

class Animal(object):
    def __init__(self,name):
        self.name = name
    def talk(self):
        print('animal [%s] is talking'%self.name)
class Dog(Animal):
    def talk(self):     #父类里已存在talk方法。子类可以进行方法重写
        print('Dog [%s] is wow wow wow'%self.name)
class Cat(Animal):
    def talk(self):
        print('Cat [%s] is miao miao miao'%self.name)
def func(obj):   #一个接口 多种形态
    obj.talk()
d=Dog('小黑')
c=Cat('小喵')
func(d)   #调用子类Dog的方法
func(c)   #调用子类Cat的方法
---------->
Dog [小黑] is wow wow wow
Cat [小喵] is miao miao miao

 类变量vs实例变量

类变量是创建类时就存在类的内存空间里面的。而实例变量是类实例化时,存在实例的内存空间里的

class People(object):
    num = 0          #类变量
    def __init__(self,name):
        self.name = name     #实例变量,通过实例来访问
    def study(self):
        People.num += 10   #  类变量使用类来访问
        print('num[%s] student %s is studing...'%(self.num,self.name))
p = People('lily')
p.study()
print(People.num)
print(p.num)
----------->
num[10] student lily is studing...
10
10
#------------错误的示例---------------------
class People(object):
    num = 0           #类变量
    def __init__(self,name):   #实例变量
        self.name = name
    def study(self):
        self.num += 10  #不能改变类变量,而是跟类变量重名的实例变量
        print('num[%s] student %s is studing...'%(self.num,self.name))
p = People('lily')
p.study()
print(People.num)
print(p.num)
----------------------->
num[10] student lily is studing...
0
10

静态方法  

@staticmethod装饰器可以把一个方法变成静态方法。  静态方法不能访问实例变量和类变量,跟类没什么关联,只能通过类名来调用方法

class People(object):
    num = 0   #类变量
    def __init__(self,name):
        self.name = name   #实例变量
    @staticmethod
    def study(self):
        print('student %s is studing...'%(self.name))  #不能访问self.num 也不能访问self.name
p = People('lily')
p.study()
------------------->
报错:study() missing 1 required positional argument: 'self'

除非把实例本身当做传给study方法 p.study(p)

类方法

@classmethod  装饰器可以把一个方法变成类方法。类方法只能访问类变量不能访问实例变量

class People(object):
    num = 0   #类变量
    def __init__(self,name):
        self.name = name   #实例变量
    @classmethod
    def study(self):
        print('num[%s] student %s is studing...'%(self.num,self.name)) #可以访问self.num 类变量,不能访问self.name实例变量
p = People('lily')
p.study()
------------->
报错AttributeError: type object 'People' has no attribute 'name'  

属性方法

@property  把一个方法变成属性

class People(object):
    def __init__(self,name):
        self.name = name
    @property   # 把study方法变成一个属性
    def study(self):
        print('student %s is studying...'%self.name)
p = People('lily')
p.study    # 属性,只读 
p.name = 'jack'   #此时外部可以调用name变量,这时可以使用__把name变成私有变量,使外部无法调用
p.study    
--------------->
student lily is studying...
student jack is studying...

p.study = 'hena'  #修改的话会报错,因为study属性不可修改
--------------->
AttributeError: can't set attribute

可以加上一个setter改为可写属性

class People(object):
    def __init__(self):
        self.__name = None
    @property   # 把study方法变成一个属性
    def study(self):
        return self.__name
    @study.setter   # 把study属性变成一个可写的属性
    def study(self,value):
        self.__name = value
    @study.deleter    #删除
    def study(self):
        del self.__name
p = People()    
print(p.study)   
p.study = 'lily'
print(p.study)
----------------->
None
lily

del p.study
print(p.study)
---------------------->     #报错,说明p.study属性已经被删除
AttributeError: 'People' object has no attribute '_People__name'

类的特殊成员方法

__str__ 和 __repr__

#不加__str__时
>>> class P:
...      def __init__(self,name,age):
...              self.name = name
...              self.age = age
>>> a=P('lily',999)
>>> print(a)
<__main__.P object at 0x7f4703aac400> 

#如果要把一个类的实例变成str,就需要用__str__
>>> class P:
...      def __init__(self,name,age):
...              self.name = name
...              self.age = age
...      def __str__(self):
...              return 'name: %s,age: %s'%(self.name,self.age)
... 
>>> b=P('xiaohei',10)
>>> b
<__main__.P object at 0x7f4703aac748>  
>>> print(b)
name: xiaohei,age: 10

#__str__()用于显示给用户看,而__repr__()是显示给开发人员看

>>> class P:
...      def __init__(self,name,age):
...              self.name = name
...              self.age = age
...      def __str__(self):
...              return 'name: %s,age: %s'%(self.name,self.age)
...      __repr__ = __str__
... 
>>> c=P('lin',20)
>>> c
name: lin,age: 20
>>> print(c)
name: lin,age: 20
View Code

__doc__  类的描述信息

class A:
    '''
    this is a test class
    '''
    def func(self):
        pass
print(A.__doc__)
-------------------------->

    this is a test class
View Code

__module__ 对象在哪个模块

# python example.py
class A:
    def func(self):
        pass
a = A()
print(a.__module__)
#结果------------------->
__main__

 # python test.py
from example import A
x = A()
print(x.__module__)
#结果------------------>
example
example
View Code

__class__ 对象是什么类

# python example.py
class A:
    def func(self):
        pass
a = A()
print(a.__class__)
----------------->
<class '__main__.A'>


# python  test.py
from example import A
x = A()
print(x.__class__)
-------------------->
<class 'example.A'>
<class 'example.A'>
View Code

__dict__    查看类或对象中的成员

class A:
    def __init__(self,name):
        self.name = name
    def func(self):
        return self.name
print("类的成员:",A.__dict__)
a = A('lily')
print("对象的成员:" ,a.__dict__)

----------------->
类的成员: {'__module__': '__main__', '__init__': <function A.__init__ at 0x0000004135DFDD08>, 'func': <function A.func at 0x0000004135DFDE18>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
对象的成员: {'name': 'lily'}
View Code

python的反射机制

getattr(object,name,[value])  获取

setattr(object, name, value)  设置

hasattr(object, name)   判断 

delattr(object, name)  删除

>>> class Myclass(object):
...      def __init__(self,name):
...              self.name = name
...      def func(self,value):
...              self.value = value
...              print("value is: ",self.value)
... 
>>> obj = Myclass("lily")
>>> hasattr(obj,"name")  #判断obj对象是否有name属性
True
>>> hasattr(Myclass,"name")  #判断类是否有name属性
False
>>> hasattr(Myclass,"func")   #判断class是否有func方法
True
>>> hasattr(obj,"func")
True

>>> getattr(obj,"name")  #获取值
'lily' 
>>> getattr(obj,"func")    #获取obj.func方法的内存地址
<bound method Myclass.func of <__main__.Myclass object at 0x7f78283302e8>>
>>> x=getattr(obj,"func")  
>>> x(22)     # 调用方法  等同于obj.func(22)
value is:  22
>>> 
>>> def test_run(server): 
...      print("%s running..."%server)
... 
>>> setattr(obj,"run",test_run)  #将test_run绑定到obj对象,命名为run
>>> obj.run("ftp")
ftp running...
import sys
class Webserver(object):
    def __init__(self,host):
        self.host = host
    def start(self):
        print("server is start...")
    def stop(self):
        print("server is stop...")
    def restart(self):
        self.start()
        self.stop()
def test_run(self,name):
    print("%s running...%s"%(name,self.host))
if __name__ == '__main__':
    s = Webserver('localhost')
    if hasattr(s,sys.argv[1]):   #判断是否有这个方法
        func = getattr(s,sys.argv[1])   #获取s.start方法的内存地址
        func()
    setattr(s,"run",test_run)
    s.run(s,'mysql')
    delattr(Webserver,'stop')  #只能类删除类方法,实例删不了,实例只能删除实例属性host
    s.restart()  #会报错'Webserver' object has no attribute 'stop'
View Code
原文地址:https://www.cnblogs.com/xiaobaozi-95/p/9546972.html