python 面向对象

   属性

          实例变量:   __init__需要初始化的变量,实例变量作用域就是实例本身
          类变量:      写在class全局的变量
          私有属性 ,如下:这样的话通过实例无法调用这个属性 。
          

          当要访问私有属性的时候,可以新建一个方法,内部方法是可以调用私有属性的,然后通过调用这个方法来获取私有属性的值:

          

          print(r1.show_status())

          如果实例调用变量,实例变量和类变量都定义了相同变量,那么优先去实例变量,没有再找类变量。 

          

    方法       

          构造方法:
                def  __init__(self):
                       self.name = name
          析构函数,在实例释放(删除实例del 或者实例运行结束),销毁的时候自动执行的,通常做一些收尾工作。如:关闭一些数据库链接,关闭打开的临时文件
                def  __del__(self):
                       do something
 
          私有方法,定义普通方法的时候前面加两个下划线 
 

对象

       实例化一个类之后得到的对象
 

封装

      把一些功能的实现细节不对外暴露
      第一个层面的封装(什么都不用做):创建类和对象会分别创建二者的名称空间,我们只能用类名.或者obj.的方式去访问里面的名字,这本身就是一种封装。
      第二个层面的封装:类中把某些属性和方法隐藏起来(或者说定义成私有的),只在类的内部使用、外部无法访问,或者留下少量接口(函数)供外部访问。 
 

继承

      代码重用
      单继承
      多继承
                 2.7经典类(class People()),深度优先,新式类(class People(object)),广度优先
                 3.x广度优先 
      
 
 
 继承例子:
class Peolpe():

    def __init__(self,name,age):
        self.name = name
        self.age = age

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

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

class Man(Peolpe): ##此处继承
    pass

m1 = Man("liyang",22)
m1.sleep()

       

继承重用

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

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

class Man(Peolpe): ##此处继承
    def eat(self):
        print("%s is eating"%self.name)
    def sleep(self):
        Peolpe.sleep(self) ##此处调用父类方法,如果没有这行,sleep方法会重写,不会执行父类方法
        print("man also is sleeping")

m1 = Man("liyang",22)
m1.sleep()

如果子类要新增初始化参数呢,要修改一下子类

class Man(People): ##此处继承
    def __init__(self,name,age,location):
        People.__init__(self,name,age) ##继承父类初始化参数
        self.location = location  ##新加一个参数

或者

class Man(People): ##此处继承
    def __init__(self,name,age,location):
        #People.__init__(self,name,age) ##继承父类初始化参数
        super(Man,self).__init__(name,age)  ##使用super内置函数,新式写法
        self.location = location  ##新加一个参数

多继承:

# -*- coding:utf-8 -*-
# Author:Brownyangyang

class People(): #经典类
    def __init__(self,name,age):
        self.name = name
        self.age = age

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

class Relation(object): #新式类写法,经典类没有object
    def make_friends(self,obj):  #obj自定义对象,和谁交朋友。self是一个对象,obj也是一个对象,这么理解
        print("%s is makeing friends with %s"%(self.name,obj.name))
        #self.name是People那边继承过来的,obj 是定义的一个实例
        #继承People()已经把name初始化了,所以继承Relation()的时候可以直接调用name,这里不需要再初始化name

class Man(People,Relation): ##此处继承
    def __init__(self,name,age,location):
        #People.__init__(self,name,age) ##继承父类初始化参数
        super(Man,self).__init__(name,age)
        self.location = location  ##新加一个参数

    def eat(self):
        print("%s is eating"%self.name)
    def sleep(self):
        People.sleep(self) ##此处调用父类方法,如果没有这行,sleep方法会重写,不会执行父类方法
        print("man also is sleeping in %s"%self.location)

class Woman(People,Relation):
    def get_birth(self):
        print("%s is borning the baby"%self.name)

m1 = Man("xiaoming",22,"nantong")

w1 = Woman("xiaohong",32)
m1.make_friends(w1)

结果:xiaoming is makeing friends with xiaohong

 

多态

        接口重用,一种接口多次实现 
 
 

方法修饰

 
静态方法 @staticmethod 
       只是名义上归类管,实际上跟类没什么关系了,实际上在静态方法里访问不了类或实例中的任何属性
 
类方法@classmethod
       只能访问类变量,不能访问实例变量
 
属性方法@property
      把一个方法变成一个静态属性 
 
 
静态方法实例
class Dog(object):
    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s is eating %s"%(self.name,food))

d = Dog("liyang")
d.eat("beaf")

结果:liyang is eating beaf

使用静态方法 @staticmethod 后

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

    @staticmethod
    def eat(self,food):
        print("%s is eating %s"%(self.name,food))

d = Dog("liyang")
d.eat("beaf")

因为不能调用实例变量和类变量,上面执行会报错:

类方法实例

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

    def eat(self):
        print("%s is eating "%self.name)

d = Dog("liyang")
d.eat()

运行结果:liyang is eating  

使用类方法@classmethod后:
class Dog(object):
    def __init__(self,name):
        self.name = name

    @classmethod  ##只加了这个
    def eat(self):
        print("%s is eating "%self.name)

d = Dog("liyang")
d.eat()

因为@classmethod 只能访问类变量,不能访问实例变量,报错如下:

如果我在类变量再定义一个那么,如下:

class Dog(object):
    name=“xiaoming”  ##在这里新定义一个name
    def __init__(self,name):
        self.name = name

    @classmethod  ##只加了这个
    def eat(self):
        print("%s is eating "%self.name)

d = Dog("liyang")
d.eat()

结果:xiaoming is eating 

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

属性方法实例:

class Dog(object):

    def __init__(self,name):
        self.name = name

    @property   ##属性方法
    def eat(self):
        print("%s is eating "%self.name)

d = Dog("liyang")
d.eat()

把一个方法变成一个静态属性,那调用方法就变了,如果不修改调用方法就会报错:

只需要 把d.eat() 改成d.eat  就可以了。

最后:

被property装饰的属性会优先于对象的属性被使用,而被propery装饰的属性,分成三种:property、被装饰

的函数名.setter、被装饰的函数名.deleter(都是以装饰器的形式)。

class people: #定义一个人的类
    def __init__(self,name,sex):
        self.name = name
        self.sex = sex #p1.sex = "male",遇到property,优先用property

    @property #查看sex的值
    def sex(self):
        return self.__sex #返回正真存值的地方

    @sex.setter #修改sex的值
    def sex(self,value):
        if not isinstance(value,str): #在设定值之前进行类型检查
            raise TypeError("性别必须是字符串类型") #不是str类型时,主动抛出异常
        self.__sex = value #类型正确的时候,直接修改__sex的值,这是值正真存放的地方
            #这里sex前加"__",对sex变形,隐藏。

    @sex.deleter #删除sex
    def sex(self):
        del self.__sex

p1 = people("egon","male") #实例化对象p1
print(p1.sex) #查看p1的sex,此时要注意self.sex的优先级
p1.sex = "female" #修改sex的值
print(p1.sex) #查看修改后p1的sex
print(p1.__dict__) #查看p1的名称空间,此时里面有sex
del p1.sex #删除p1的sex
print(p1.__dict__) #查看p1的名称空间,此时发现里面已经没有sex了

结果:

male
female
{'name''egon''_people__sex''female'}
{'name''egon'}
原文地址:https://www.cnblogs.com/brownyangyang/p/9060207.html