• python学习笔记(12):高级面向对象


    一、__slots__和property

      1.__slots__魔术函数动态的添加方法和属性

      2.直接暴露属性的局限性

      3.使用get/set方法

      4.利用@property简化get/set方法

      5.利用@property实现只读属性

      6.装饰器与property实现

     # import traceback
    # from types import MethodType
    #
    # class MyClass(object):
    #     # pass
    #     #在做新的类的时候,限制动态添加的属性,这个时候需要用到__slots__魔术变量,系统内为了实现某些特定功能的
    #     __slots__ = ['name','set_name']    # 这个地方,能添加的属性和方法就会受到限制,只能添加name或者set_name这两个名词的属性或者方法
    # def set_name(self,name):
    #     self.name = name
    # cls = MyClass()  #实例化类
    # cls.name='Tom'   #动态的添加属性
    # cls.set_name=MethodType(set_name,cls)  #动态的添加方法  将set_name作用于cls上面
    # cls.set_name('Jerry')
    # print(cls.name)
    # try:
    #     cls.age=30   #动态添加属性  ,这个地方要注意,age不在__slots__规定的数组中,所以会报错
    # except AttributeError:
    #     traceback.print_exc()  #打印出异常信息   AttributeError: 'MyClass' object has no attribute 'age'
    #
    # class ExtMyClass(MyClass):  #继承自MyClass
    #     pass
    # ext_cls = ExtMyClass()
    # ext_cls.age=30
    # print(ext_cls.age)

      2.property

    import traceback
    class Student:
        @property   # 这个地方用装饰器进行修饰的时候,实际上是生成了一个新的对象,名字叫做score,这个相当于set函数
        def score(self):
            return self._score
        @score.setter
        def score(self,value):
            if not isinstance(value,int):   #进行value的类型检查,如果不是int型的值,就会报错not int
                raise ValueError('not int')
    
            elif (value<0) or (value>100):   #如果value只不是在这个区间之间的话,就会报错值不在0~100之间,这个地方相当于get函数
                raise ValueError('not between 0 ~ 100')
            self._score=value
    
        @property   #注意,这里没有set方法,所以只能读取,不能写
        def double_score(self):
            return self._score*2
    s= Student()
    s.score=75
    print(s.score)
    print(s.double_score)
    try:
        s.double_score=150
    except AttributeError:
        traceback.print_exc()
    
    try:
        s.score='abc'
    except ValueError:
        traceback.print_exc()
    try:
        s.score=101
    except ValueError:
        traceback.print_exc()

      3.枚举类

    from enum import Enum
    
    Month = Enum('Month',('Jan','Feb','Mar','Apr'))
    
    for name,member in Month.__members__.items():
        print(name,'=>',member,',',member.value)
    
    jan = Month.Jan
    print(jan)

    二、元类

      1.运行时动态创建 vs 编译时定义

    def init(self,name):  #自定义构造函数,
        self.name=name
    def say_hello(self):   #自定义成员函数
        print('hello, %s!' %self.name)
    
    Hello = type('Hello',(object, ),dict(__init__ = init,hello=say_hello))  #(object, )是一个基类的列表
    
    """
        这个地方的代码等价于下面的这些代码:
             class Hello:
                def __init__(.......)
                def hello(..........)
    """
    h = Hello('Tom')
    h.hello()

      2.使用type创建新类型

      3.metaclass(元类)

        (1)metaclass -> class -> instance

        (2)继承和动态绑定可以解决问题吗?

        (3)__new__函数

    class ListMetaclass(type):
        def __new__(cls,name,bases,attrs):
            # print(cls)   #打印出传进来的类时什么
            # print(name)   #打印出传进来的name是什么
            # print(bases)   #打印出传入进来的基类是什么   基类是list类
            attrs['add'] = lambda self,value:self.append(value)
            return type.__new__(cls,name,bases,attrs)
    class MyList(list,metaclass=ListMetaclass):  #从list类继承下来,就是一个数组,但是额外的增加add方法,实际等价于append
        pass
    mli = MyList()
    mli.add(1)
    mli.add(2)
    mli.add(3)
    print(mli) 

    三、ORM框架实例(重点的重点)

  • 相关阅读:
    Solr6.6环境安装及core的创建(win7环境)
    使用Druid作为数据源
    Windows远程数据同步工具cwRsync
    解读zookeeper的配置项
    堵塞与非堵塞原理
    Apache Hadoop2.0之HDFS均衡操作分析
    转到简书去了
    淘宝技术这十年概要
    Facebook广告API系列 Business Manager
    Facebook广告API系列 3 Ads Management
  • 原文地址:https://www.cnblogs.com/bigdata-stone/p/10198730.html
Copyright © 2020-2023  润新知