设为首页 收藏本站
查看: 1517|回复: 0

[经验分享] python_day6_对象

[复制链接]

尚未签到

发表于 2018-8-8 07:51:08 | 显示全部楼层 |阅读模式
  6.1:类与对象
  类、对象
  实例:增删改查
  6.2:类调用方式
  普通调用方式:
  静态属性
  类方法
  类的工具包
  6.3: 三大特性: 继承,封闭,派生
  继承顺序:mro
  子类调用父类的方法
  supper()
  多态
  封装
  私有属性
  6.4: 常用术语
  合成
  派生/继承/继承结构
  泛化/特化
  多态与多态性
  自省/反射
  python是一门面向对象编程语言,其中编程方式分为三种范式:
  1、面向过程编程
  2、函数式编程
  分为两种:数学层次的编程与python函数式编程
  3、面向对象编程
  对象是由类产生的具体存在
  6.1: 类与对象
  什么是类:
  类:把一类事物的相同的特征和动作整合到一起就是类,类是一个抽象的概念
  什么是对象:
  对象:就是基于类而创建的一个具体的事物(具体存在的),也是特征和动作整合到一起。
  面向对象设计: 把一类事物的相同的数据和动作整合到一起,即是面向对象设计
def Botany(name,variety,type):  
    # 特征,名称,品种,类型
  
    def init(name,variety,type):
  
        Bot = {
  
            'Name':name,
  
            'variety':variety,
  
            'type':type,
  
            'see':see
  
        }
  
        return Bot
  
    # 动作,查看一下它
  
    def see(Botany):
  
        print('这是一朵 %s花' %Botany['Name'])
  

  
    return init(name,variety,type)
  

  
fy=Botany('玫瑰','花','观赏类')
  
print(fy)
  
fy['see'](fy)
  

  
结果:
  
{'Name': '玫瑰', 'variety': '花', 'type': '观赏类', 'see': <function Botany.<locals>.see at 0x00000000027CF840>}
  
这是一朵 玫瑰花
  面向对象编程: 用定义类+实例/对象的方式去实现面向对象的设计
  类:
class 类名:           经典类  
  pass
  

  
class 类名(object):   新式类
  
  pass
  # 在python3中,上述两种定义方式全都是新式类
  class.__dict__   查看类的属性字典
class te1:  
    def __init__(self,name):
  
        self.name = name
  

  
    def play_tv(self):
  
        print('%s 正在看电视'%self.name)
  

  
def in_name():
  
    name=input('请输入名称: ')           # 类的每个功能体都必须放开,init也可以定义,init建议只存放字典类数据
  
    p1=te1(name)
  
    p1.play_tv()
  
in_name()
  结果:
请输入名称: xx  
xx 正在看电视
  实例:指的是类生成的某个对象,调用 __init__ 的过程
  实例应当具备类的特征以及数据属性
  实例没有函数属性, 函数属性只属于类
  实例只建议使用查,不建议修改或增加函数。
  # 创建一个类
class te1:  
    # 创建构造方法
  
    def __init__(self,name,age,gender):
  
        self.name = name
  
        self.age = age
  
        self.gender = gender
  

  
huan=te1('huan',111,'man')
  

  
# 查看类的字典
  
print(huan.__dict__)    # {'name': 'huan', 'age': 111, 'gender': 'man'}
  

  
# 修改
  
huan.age='222'
  
print(huan.age)         # 222
  

  
# 增加一个键值对
  
huan.__dict__['hu']='test'
  
print(huan.__dict__)            # {'name': 'huan', 'age': '222', 'gender': 'man', 'hu': 'test'}
  

  
# 删除
  
del huan.age
  
print(huan.__dict__)    # {'name': 'huan', 'gender': 'man'}
  # 说明
  # self: 调用实例属性
  # cls:  调用类属性
  6.2:类调用方式
  # 普通调用方式:
class Cup:  
    def __init__(self,name,size,type):
  
        self.Name = name
  
        self.Size = size
  
        self.Type = type
  

  
    def info(self):
  
        print('the cup name is: %s size: %s type: %s'%(self.Name,self.Size,self.Type))
  

  
c1=Cup('mo','11','bf')
  
c1.info()
  
# 结果: the cup name is: mo size: 11 type: bf
  静态属性: 将函数封闭成数据属性的格式,调用时可直接忽略执行时的逻辑
  # 错误的调用方式
@property  
def info(self):
  
    print('the cup name is: %s size: %s type: %s'%(self.Name,self.Size,self.Type))
  
c1=Cup('mo','11','bf')
  
c1.info()
  
# 直接像这样调用会报错:TypeError: 'NoneType' object is not callable
  # 正确调用方式:  静态属性,调用方式像数据属性一样调用就行。
@property  
def info(self):
  
    return 'the cup name is: %s size: %s type: %s'%(self.Name,self.Size,self.Type)
  

  
c1=Cup('mo','11','bf')
  
print(c1.info)
  

  
# 结果:   the cup name is: mo size: 11 type: bf
  # 类方法: 不跟具体实例捆绑,只跟类捆绑使用, 不需要实例化,直接用类就可以使用
class Cup:  
    tags=1
  
    @classmethod          # 如果有类调用函数的需求那么直接使用类方法即可
  

  
    def tag_info(cls):
  
        print(cls)
  

  
Cup.tag_info()
  
print('类方法调用: %s' %cls.tags)
  

  
# 打印结果: <class '__main__.Cup'>
  
   类方法调用: 1
  # 类的工具包, 不跟类绑定,也不跟具体实例绑定
  @staticmethod    跟类跟实例都没有关系
@staticmethod  
def info_sta(x,y):
  
    print('这里是类方式%s %s'%(x,y))
  

  
Cup.info_sta(1,2)
  
# 打印结果: 这里是类方式1 2
  

  
# 如果直接使用实例调用
  
c1=Cup('mo','11','bf')
  
c1.info_sta(1,2)
  
# 打印结果: 这里是类方式1 2 与直接类使用一样,但实际调用的只是这个方法的类的工具包
  # 不带self,cls的调用方式与类工具包的区别
def test2(x,y):  
print('这里是普通函数: %s %s'%(x,y))
  

  
Cup.test2(3,2)
  
# 打印结果: 这里是普通函数: 3 2
  

  
c1.test2(3,2)     # 实例会执行它里会调用c1的实例在传递到self中,这里这个函数只是普通函数方式
  
# 调用实例打印: TypeError: test2() takes 2 positional arguments but 3 were given
  # 类工具与普通函数,使用字典查看它俩的区别
'info_sta': <staticmethod object at 0x0000000002982198>,  
'test2': <function Cup.test2 at 0x000000000297F8C8>
  三大特性: 继承,封闭,派生
  # 继承 子类会继承父类的所有属性,如果子父有相同的数据或方法,子类不会覆盖父类的任何数据
class Up1:  
    # 先来个数据属性
  
    cat='Public'
  
    # 再来个方法
  
    def __init__(self,name):
  
        self.name = name
  

  
    def Garage(self,name):
  
        print('这是一辆好车%s '%self.name)
  

  
class Down1(Up1):
  
    pass
  

  
do=Down1('rolls-royce')
  
do.Garage(do)
  
print(do.cat)
  # 接口继承 ---------------------------------------------------------------------------------------
class Alls:  
    def eat(self):
  
        pass
  

  
    def sleep(self):
  
        pass
  

  
class human(Alls):
  
    def eat(self):
  
        print('eat food')
  
    # def sleep(self):
  
    #     print('slepp night')
  

  
h1=human()
  
h1.eat()
  
h1.sleep()
  # 上面的代码只是看起来像接口,其实并没有起到接口的作用,子类完全可以不用去实现接口 ,这就用到了抽象类
  # 接口继承、抽象类:定义一个基类,基类当中把自己的方法定义成接口函数,只要来一个子类,那么子类必须实现它的方法才能执行
  1 什么是抽象类
  与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化
  2 为什么要有抽象类
  如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。
  比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子。。。。。。你永远无法吃到一个叫做水果的东西。
  从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的。
  从实现角度来看,抽象类与普通类的不同之处在于:抽象类中只能有抽象方法(没有实现功能),该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似,但其实是不同的,即将揭晓答案  来源于: http://www.cnblogs.com/linhaifeng/articles/7340153.html
import abc  # 定义抽象层  
class Alls(metaclass=abc.ABCMeta):
  
    @abc.abstractstaticmethod       #定义抽象方法,无需实现功能
  
    def eat(self):
  
        pass
  
    @abc.abstractstaticmethod
  
    def sleep(self):
  
        pass
  

  
class human(Alls):      #子类继承抽象类,但是必须定义eat和sleep方法
  
    def eat(self):
  
        print('eat food')
  
    # def sleep(self):
  
    #     print('slepp night')
  

  
h1=human()
  
h1.eat()
  
h1.sleep()  # 打印结果:TypeError: Can't instantiate abstract class human with abstract methods sleep
  
# 父类中定义的方法,子类中必须要有,可以不实现功能,但是方法必须有以实现接口功能
  # 继承顺序:
  py2分深度和广度优先,
  Py3只有广度优先
  # 深度优先: 从左开始查找,一直到类的最深处
  # 广度优先: 从左开始不找到最后,然后从右开始找到最后
  MRO: 方向解析顺序
  # 方法示例:  F --> C -->  B --> A
  --> E -->  D --> A
class A:  
def test(self):
  
    print('A')
  

  
class B(A):
  
    def test(self):
  
        print('B-a')
  

  
class C(B):
  
    def test(self):
  
        print('C-B-A')
  

  
class D(A):
  
    def test(self):
  
        print('D-A')
  

  
class E(D):
  
    def test(self):
  
        print('E-D-A')
  

  
class F(C,E):
  
    # def test(self):
  
        # print('F')
  
    pass
  

  
f1=F()
  
f1.test()    # 打印结果为: C-B-A
  1.子类会先于父类被检查
  2.多个父类会根据它们在列表中的顺序被检查
  3.如果对下一个类存在两个合法的选择,选择第一个父类
  # 继承顺序 查看 print(F.__mro__):
# (<class '__main__.F'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>)  # 子类调用父类的方法
class cat:  
def __init__(self,name,high,long,wide):
  
    self.name = name
  
    self.high = high
  
    self.long = long
  
    self.wide = wide
  

  
def stat(self):
  
    print('%s 开动'%self.name)
  

  
class Public(cat):
  
    # 这个self指的是这个类的__init__方法调用的self值,然后再传递到上层init中
  
    def __init__(self,name,high,long,wide,price):
  
        cat.__init__(self,name,high,long,wide)
  
        self.price = price
  

  
    def stat(self):
  
        cat.stat(self)      #public 开动
  
        # public 这个车价格 10000
  
        print('%s 这个车价格 %s'%(self.name,self.price))
  

  
# 实例化这个对象
  
pu1=Public('public','210cm','600cm','400cm',10000)
  
# 执行类的方法
  
pu1.stat()
  # supper().  继承父类,使用直接supper().方法, 当父类名改变之后,只需要更改类的父类名,不需要更改代码的逻辑
  # 使用supper 的好处: 当父类名更改时,程序代码不需要理性,并且不需要再传递self参数
class Public(cat):  
    def __init__(self,name,high,long,wide,price):
  
        super().__init__(name,high,long,wide)               # 这三种使用方式都是同一个意思
  
        # super(Public,self).__init__(name,high,long,wide)
  
        # super(__class__,self).__init__(name,high,long,wide)
  
        # cat.__init__(self,name,high,long,wide)
  
        self.price = price
  

  
    def stat(self):
  
        super().stat()
  
        # cat.stat(self)      #public 开动
  
        # public 这个车价格 10000
  
        print('%s 这个车价格 %s'%(self.name,self.price))
  

  
# 实例化这个对象
  
pu1=Public('public','210cm','600cm','400cm',10000)
  
# 执行类的方法
  
pu1.stat()
  # 什么是多态: 由不同的类实例化得到的对象,调用同一个方法,执行的逻辑不同
  # 多态的概念指出了对象如何通过他们共同的属性和动作来操作及访问,而不需考虑他们具体的类 如len
  # 多态是由继承体现的一种方式
  # 多态
  # 类的继承有两层意义: 1、改变 2、扩展
  # 多态的就是类的这两层意义的一个具体的实现机制即、调用不同的类实例化得对象下的相同的方法,实现的过程不一样
  # python中的标准类型就是多态概念的一个很好的示范
class water:  
    def __init__(self,name,temperature):
  
        self.name = name
  
        self.temperature = temperature
  

  
    def func(self):
  
        if self.temperature < 0:
  
            print('[%s] 会结冰'%self.name)
  
        elif self.temperature>0 and self.temperature < 50:
  
            print('[%s] 液化为水'%self.name)
  
        elif self.temperature > 51:
  
            print('[%s] 成为水蒸气'%self.name)
  

  
class wa(water):
  
    pass
  

  
w1=wa('水',10)
  # 由不同的类实例化得到的对象,调用同一个方法,执行的逻辑不同
    def func(objs):  
        objs.func()
  

  
    func(w1)    # w1.func()     # 都是调用同一个方法,但执行的逻辑不同
  # 封装

  #>class pople:  
data = 'water'
  

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

  
def start(self):
  
print('社保ID: %s, 名字: %s, 住宅: %s' %(self.id,self.name,self.addr))
  # 调用封装属性
from Characteristic import pople  

  
# 生成一个实例,并调用未知的属性
  
p1=pople('12321','xiong','天朝')
  
p1.start()      # 社保ID: 12321, 名字: xiong, 住宅: 天朝
  # 约定规则,不要使用约定的隐藏属性
  _ : python当中的约定,只要属性是单下划线下头的,就表示是一个隐藏属性, 外部无法调用,(其实外部可以调用,这只是py的一种约定,_表示不要使用这种属性内容)
print(pople._data)      # _代表py与用户的约定,_表示这个是一个隐藏属性,用户不应该再使用它  __ : python会自动重命名为  _classname__属性名,
  # 直接使用这个数据属性,一看认为它就是一个隐藏属性,无法调用其实不然
print(pople.__data)     # AttributeError: type object 'pople' has no attribute '__data'  

  
print(pople.__dict__)   # 使用dict查看类的方法里,里面包含了 '_pople__data': 'water', py会自动重命名这个数据属性
  

  
print(pople._pople__data)   # 使用重命名的再次查看也能查询到water

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-548397-1-1.html 上篇帖子: python发送短信 下篇帖子: python_day9_socket
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表