面向对象是为了能够更好的维护更新我们的程序而存在的,数据工厂一样开发过程,站在上帝的角度考虑,

我们看到的是就好像是一个列表a = [ 1, 2] ,这个列表有什么功能,这些是内置的,而我们可以同创造出这

样的一个列表,同时列表的功能有我们自由决定,如何俩狗实现高度的自由,这就是这篇文章要解释   的,

关于面向对象的特性封装,通过封装可以达到自已的控制类的特性,你就是真正的主宰,看如下代码演示:

封装的真谛在于明确地区分内外,封装的属性可以直接在内部使用,而不能被外部直接使用,然而定义属性的目的终归是要用,外部要想用类隐藏的属性,需要我们为其开辟接口,让外部能够间接地用到我们隐藏起来的属性,那这么做的意义何在???

1:封装数据:将数据隐藏起来这不是目的。隐藏起来然后对外提供操作该数据的接口,然后我们可以在接口附加上对该数据操作的限制,以此完成对数据属性操作的严格控制。

class Teacher:
    def __init__(self,name,age):
        # self.__name=name
        # self.__age=age
        self.set_info(name,age)

    def tell_info(self):
        print('姓名:%s,年龄:%s' %(self.__name,self.__age))
    def set_info(self,name,age):
        if not isinstance(name,str):
            raise TypeError('姓名必须是字符串类型')
        if not isinstance(age,int):
            raise TypeError('年龄必须是整型')
        self.__name=name
        self.__age=age


t=Teacher('egon',18)
t.tell_info()

t.set_info('egon',19)
t.tell_info()

面向对象的 特性 什么是特性property

相当于制造一个伪装饰器

class People:
    def __init__(self,name, weight, height):
        self.name = name
        self.weight = weight
        self.height = height
    @property
    def bmi(self):
            return self.weight / (self.height **2)
albert = People('albert',63,1.65)
drama = People('drama',49,1.71)
print(albert.bmi)
print(drama.bmi)

  

为什么要用property

将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

除此之外,看下

复制代码
ps:面向对象的封装有三种方式:
【public】
这种其实就是不封装,是对外公开的
【protected】
这种封装方式对外不公开,但对朋友(friend)或者子类(形象的说法是“儿子”,但我不知道为什么大家 不说“女儿”,就像“parent”本来是“父母”的意思,但中文都是叫“父类”)公开
【private】
这种封装对谁都不公开
复制代码

python并没有在语法上把它们三个内建到自己的class机制中,在C++里一般会将所有的所有的数据都设置为私有的,然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现

复制代码
class Foo:
    def __init__(self,val):
        self.__NAME=val #将所有的数据属性都隐藏起来

    @property
    def name(self):
        return self.__NAME #obj.name访问的是self.__NAME(这也是真实值的存放位置)

    @name.setter
    def name(self,value):
        if not isinstance(value,str):  #在设定值之前进行类型检查
            raise TypeError('%s must be str' %value)
        self.__NAME=value #通过类型检查后,将值value存放到真实的位置self.__NAME

    @name.deleter
    def name(self):
        raise TypeError('Can not delete')

f=Foo('egon')
print(f.name)
# f.name=10 #抛出异常'TypeError: 10 must be str'
del f.name #抛出异常'TypeError: Can not delete'
复制代码

@property可以将python定义的函数“当做”属性访问,从而提供更加友好访问方式,但是有时候setter/deleter也是需要的。
1》只有@property表示只读。
2》同时有@property和@x.setter表示可读可写。

3》同时有@property和@x.setter和@x.deleter表示可读可写可删除。

[python] view plain copy
class student(object):  #新式类  
    def __init__(self,id):    
        self.__id=id    
    @property  #
    def score(self):    
        return self._score    
    @score.setter #
    def score(self,value):    
        if not isinstance(value,int):    
            raise ValueError('score must be an integer!')      
        if value<0 or value>100:    
            raise ValueError('score must between 0 and 100')     
        self._score=value    
    @property #读(只能读,不能写)    
    def get_id(self):    
        return self.__id    
    
s=student('123456')    
s.score=60 #
print s.score #
#s.score=-2 #ValueError: score must between 0 and 100    
#s.score=32.6 #ValueError: score must be an integer!    
s.score=100 #
print s.score #
print s.get_id #读(只能读,不可写)  
#s.get_id=456 #只能读,不可写:AttributeError: can't set attribute  

运行结果:
60
100
123456

1 什么是多态
多态指的是同一种事物多种形态


2、为什要用多态
用基类创建一套统一的规则,强制子类去遵循(使用抽象类实现),这样便可以
在不用考虑对象具体类型的前提下而直接使用对象下的方法

3、如何用多态
import abc
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def eat(self):
        pass
    @abc.abstractmethod
    def drink(self):
        pass
    @abc.abstractmethod
    def run(self):
        pass
class Cat(Animal):
    def eat(self):
        print('cat eat')

    def drink(self):
        print('cat drink')

    def run(self):
        print('cat run')

    def bark(self):
        print('喵喵喵')
# obj=Animal() # 抽象基类本身不能被实例化

class Cat(Animal):
    def eat(self):
        print('cat eat')

    def drink(self):
        print('cat drink')

    def run(self):
        print('cat run')

    def bark(self):
        print('喵喵喵')
c=Cat()
c.BARK()

len函数的原理

s='hello'
l=[1,2,3]
t=(4,5,6)

s.__len__()
l.__len__()
t.__len__()


# def LEN(obj):
#     return obj.__len__()
#
print(LEN(s))
print(LEN(l))
print(LEN(t))
print(len(l))
print(len(s))
print(len(t))

鸭子类型

class Foo:
    def f1(self):
        print('from foo.f1')

    def f2(self):
        print('from foo.f2')

class Bar:
    def f1(self):
        print('from bar.f1')

    def f2(self):
        print('from bar.f2')


obj1=Foo()
obj2=Bar()


obj1.f1()
obj1.f2()

obj2.f1()
obj2.f2()




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

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


class Txt:
    def read(self):
        print('txt read')

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


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

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


obj1=Disk()
obj2=Txt()
obj3=Process()


obj1.read()
obj2.read()
obj3.read()

 

绑定方法:    
在类内部定义的函数,默认就是给对象来用,而且是绑定给对象用的,称为对象的绑定方法
绑定对象的方法特殊之处:
应该由对象来调用,对象来调用,会自动将对象当作第一个参数传入

绑定到类的方法特殊之处:
应该由类来调用,类来调用,会自动将类当作第一个参数传入
staticmethod:非绑定方法,就是一个普通函数
#特性:既不跟类绑定,也不跟对象绑定,这意味着谁都能用
#谁来用都是一个普通函数,也就是说没有自动传值的特性了
classmethod:类的调用
import settings
import hashlib
import time

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

    def tell(self):
        print('%s: %s:%s' %(self.uid,self.name,self.age))

    @classmethod
    def from_conf(cls):
        return cls(settings.NAME,settings.AGE)

    @staticmethod
    def create_id():
        m=hashlib.md5()
        m.update(str(time.clock()).encode('utf-8'))
        return m.hexdigest()

obj=People('egon',18)
print(obj.create_id())
print(People.create_id())

 


 

版权声明:本文为mayite原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/mayite/p/8856633.html