一、__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= #动态添加属性 ,这个地方要注意,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=
# 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<) or (value>): #如果value只不是在这个区间之间的话,就会报错值不在0~100之间,这个地方相当于get函数
raise ValueError('not between 0 ~ 100')
self._score=value @property #注意,这里没有set方法,所以只能读取,不能写
def double_score(self):
return self._score*
s= Student()
s.score=
print(s.score)
print(s.double_score)
try:
s.double_score=
except AttributeError:
traceback.print_exc() try:
s.score='abc'
except ValueError:
traceback.print_exc()
try:
s.score=
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()
mli.add()
mli.add()
print(mli)

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

python学习笔记(12):高级面向对象的更多相关文章

  1. python 学习笔记 12 -- 写一个脚本获取城市天气信息

    近期在玩树莓派,前面写过一篇在树莓派上使用1602液晶显示屏,那么可以显示后最重要的就是显示什么的问题了. 最easy想到的就是显示时间啊,CPU利用率啊.IP地址之类的.那么我认为呢,假设可以显示当 ...

  2. python学习笔记12 ----线程、进程

    进程和线程的概念 进程和线程是操作系统中两个很重要的概念,对于一般的程序,可能有若干个进程,每一个进程有若干个同时执行的线程.进程是资源管理的最小单位,线程是程序执行的最小单位(线程可共享同一进程里的 ...

  3. python学习笔记六 初识面向对象上(基础篇)

    python面向对象   面向对象编程(Object-Oriented Programming )介绍   对于编程语言的初学者来讲,OOP不是一个很容易理解的编程方式,虽然大家都知道OOP的三大特性 ...

  4. python学习笔记15(面向对象编程)

    虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程. 一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界 ...

  5. python 学习笔记9(面向对象)

    面向过程.函数式.面向对象 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象(Object Oriented Programmin ...

  6. python 学习笔记12(事件驱动、IO多路复用、异步IO)

    阻塞IO和非阻塞IO.同步IO和异步IO的区别 讨论背景:Linux环境下的network IO. 1.先决条件(几个重要概念) 1.1.用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32 ...

  7. Python学习笔记4 高级特性_20170618

    # 切片(获取list / tuple / 字符串 中指定的元素) l = list(range(10)) l[0:3] l[:3] # 0可以省略 l[:] # 全部 l[3:] # 最后的可以省略 ...

  8. 吴裕雄--天生自然python学习笔记:Python3 面向对象

    Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的. 面向对象技术简介 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了该集 ...

  9. Python学习笔记12—类

    典型的类和调用方法: #!/usr/bin/env Python # coding=utf-8 __metaclass__ = type #新式类 class Person: #创建类 def __i ...

随机推荐

  1. 3分钟教会你把封装的js公共方法挂载在vue实例原型上

    第一步:首先在src文件夹里面创建一个通用js文件夹,然后在创建的文件夹里面创建一个js文件 第二步:const 一个方法,然后通过export暴露出来(在同一个页面可以写多个方法,和暴露多个方法,在 ...

  2. Liunx的软链接和硬链接

    ln 命令  命令名称: ln. 英文原意: make links between file. 所在路径: /bin/ln. 执行权限:所有用户. 功能描述:在文件之间建立链接. ln 命令 ...

  3. onload in JavaScript

    https://www.w3schools.com/tags/ev_onload.asp Example Execute a JavaScript immediately after a page h ...

  4. PCIE手札

    PCIE兼容了大部分PCI总线的特性,区别在于使用串行差分总线代替了并行总线,并实现了协议分层.PCIE的带宽与LANE数量和时钟频率相关,时钟频率支持2.5G和5G,Lane支持x1/x2/x4/x ...

  5. 【洛谷P5018 对称二叉树】

    话说这图也太大了吧 这题十分的简单,我们可以用两个指针指向左右两个对称的东西,然后比较就行了 复杂度O(n*logn) #include<bits/stdc++.h> using name ...

  6. 【HTML】<!DOCTYPE html>作用

    1.定义: DOCTYPE标签是一种标准通用标记语言的文档类型声明,它的目的是要告诉标准通用标记语言解析器,它应该使用什么样的文档类型定义(DTD)来解析文档. <!DOCTYPE> 声明 ...

  7. ubuntu 安装maven

    1.下载maven文件 切换目录 root@ubuntu:~# cd /usr/local 下载文件 root@ubuntu:/usr/local# wget http://mirror.bit.ed ...

  8. 三种方式创建bean对象在springIOC容器中初始化、销毁阶段要调用的自定义方法

    1. 使用@Bean注解定义initMethod和destroyMethod 所谓initMethod和destroyMethod,是指在springIOC容器中,对于bean对象执行到初始化阶段和销 ...

  9. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_07 缓冲流_3_BufferedInputStream_字节缓冲

    内容改成abc 来个数组缓冲

  10. 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_02 泛型_1_泛型的概念

    ArrayList的源码,.在定义的时候用到了E这个E就是一个未知类型 ArrayList里面的add方法,参数也是E 包括我们之前常用的get方法 返回值也是E 类型什么时候可以确定呢?创建集合对象 ...