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()
扫描二维码关注公众号,回复: 4708200 查看本文章

  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框架实例(重点的重点)

猜你喜欢

转载自www.cnblogs.com/bigdata-stone/p/10198730.html