文档章节

Python3类

夏洛特_
 夏洛特_
发布于 2016/11/03 19:23
字数 1774
阅读 15
收藏 0

1.类的定义

class Heap:
#    def __new__(cls):  # 创建实例,传入cls类本身
#        # 可以改变实例创建的行为,这就是元编程的体现
#        pass # 通常不写,除非要改变默认的创建实例的行为
# 所有类的__class__都是type或其子类的实例
    class_var = 1 # 类变量,被实例共享引用,可被类.操作修改,赋值修改后产生个性化
    class_list = [] # 类可变变量,赋值改变,修改不变

    # 对象创建完成后,立刻执行,self代表实例本身
    def __init__(self, *args, **kwargs): # 通常叫做构造函数,在python中更多的叫做初始化函数
        self.kwargs = kwargs # 没有显示定义__init__时,会使用默认的__init_
        self.x = x # 普通实例变量
        self.__y = y # 仅双下划线开始的变量是私有实例变量,理论上,仅可被内部方法访问;实际上._类名__私有变量__
        self._z = z # 单下划线开始的变量是共有的
        self.__m__ = 1 # 双下划线开始结尾的变量是公有的(特殊)
    
    def add(self, x): # 实例方法
        pass # “第一个参数”必须是self
    
    @classmethod #使用装饰器,定义类方法,用于让实例能调用
    def method_of_class(cls): # “第一个参数”是cls,类本身
        print('method of class')
        
    @staticmethod # 用于让实例能调用
    def static_method(): # 静态方法,默认不能被实例调用
        print('static method') # 不传入“第一个参数”

2.类的封装

class G:
    __private_var = 'private'
    status1 = '...'

    @property # 使用装饰器,把x方法装饰为属性,通过.操作直接访问
    def status1(self):
        return self.__private_var
    
    @status1.setter # 被x.setter装饰的方法,使方法属性可被直接修改
    def status11(self, value):
        if value in ('closed', 'openning'):
            self.__private_var = value
        else:
            raise ValueError(value)
            
    @status1.deleter
    def status1(self):
        raise NotImplementedError('you can nott')

类变量、方法属性、实例变量,会根据代码的执行顺序进行覆盖:

    类变量、方法属性是定义类的时候定义的,所以会根据代码写的顺序进行覆盖

    实例变量在类定义后实例化的时候定义

3.类的继承

# 所有类都继承于object类
class H(G): # H类继承G类,会创建H类MRO表
    def print(self):
        print('i am H')
        super().print() # 调用H父类的方法
        super(G, self).print() # 调用G父类的方法
        #print(super().private) # 无法访问父类的实例变量
        #print(super().pub) # 可访问类变量

H.mro()
[__main__.H, __main__.G, __main__.Base, object]
可通过super(type, self),返回type的父类(准确来说是mro表的下一个类)的指代super对象,进行调用type类的方法

4.运算符重载

class Complex:
    def __init__(self, real, imag=0): # 方法前后双下划线,称为专有方法或魔术方法
        self.real = real
        self.imag = imag
    # 重载int类方法
    def __add__(self, other): # 重载+法,只能__add__跟默认的+方法重载
        return Complex(self.real + other.real, self.imag + other.imag)
    
    def __sub__(self, other): # 重载-法,只能__sub__跟默认的-方法重载
        return Complex(self.real - other.real, self.imag - other.imag)
    
    def __mul__(self, other): # 重载*法,只能__mul__
        return Complex(self.real * other.real - self.imag * other.imag,
                      self.real * other.imag + self.imag * other.imag)

5.内建方法

class A:
    def __init__(self):
        self.length = 1
    
    def __len__(self):
        return self.length
    
    def __bool__(self):
        return False
a = A()
len(a)
bool(a)

6.可调用对象

class Add:
    def __call__(self, a, b):#有__call__方法的对象,是可调用对象,可以直接调用
        return a + b # __init__ 有__call__方法

a = Add() # 所有函数都是可调用对象
a(1, 2) # 当调用一个可调用对象时,实际上调用的是__call__方法
3

callable(a) # 内置函数callable用于判断一个对象是否是可调用对象
True

7.对象可视化

class Complex:
    def __init__(self, real, imag=0):
        self.real = real
        self.imag = imag
    
    def __str__(self):
        if self.imag > 0:
            return ' {} + {}i'.format(self.real, self.imag)
        elif self.imag < 0:
            return ' {} - {}i'.format(self.real, self.imag * -1)
        return ' {}'.format(self.real)
    
    def __repr__(self):
        return '<{}.{}({}, {}) at {}>'.format(self.__module__, self.__class__.__name__, self.real, self.imag, hex(id(self)))

c = Complex(1, 2)
str(c)
' 1 + 2i'

c
<__main__.Complex at 0x7f88f5eb7a58>
<__main__.Complex(2, 3) at 0x7f88f5ed25f8> # 修改了__repr__方法后

8.context

class Context:
    def __init__(self):
        print('init')
    # 同时具有__enter__和__exit__方法的类
    def __enter__(self):
        print('enter')
        
    def __exit__(self, *args, **kwargs):
        print('exit')
with Context()as a: # with后面跟一个实例,as把__enter__方法的返回值赋给a
    print('block') # 按照__init__,__enter__,block,__exit__顺序执行

成对出现操作,并且必须确保两个都执行
    资源打开/关闭
    枷锁/解锁
进入代码块之前要执行一些操作(__enter__)
    初始化
    权限判断
离开代码块时要执行一些操作(__exit__)
# 标准库里的context装饰器
import contextlib
@contextlib.contextmanager
def test():
    print('enter') # __enter__
    try:
        yield 123 # block
    finally:
        print('exit') # __exit__

9.反射

#通俗:可以使用代码,获取对象本身的一些属性,例如对象的字段、方法等
dir(a) # 获取实例的属性和方法
a.__class__ # 获取当前模块类
__main__.A
a.__class__.__name__ # 获取当前类名
'A'
a.__dict__ # 获取属性
{'y': 1}
a.__doc__ # 文档字符串'''doc'''
a.__module__ # 当前所在模块
'__main__'
class A:
    x = 1
    
    def __init__(self):
        self.y = 1
    # getattr 内建函数,调用 __getattribute__,通过字符串的方式访问类的属性
    # 如果类定义了__getattr__ 方法,当输出不存在时,将会访问__getattr__方法
    def __getattr__(self, name, default=None):
        return 'missing proptery'
    # 当定义__getattribute__方法的时候,访问实例的属性的时候,总是调用__getattrbute__
    def __getattribute__(self, *args, **kwargs):
        return '1111'
    
a = A()
setattr(a, 'x', 3) # setattr设置object属性(实际调用__setattr__),存在即修改,不存在即创建
delattr(a, 'num') # 删除属性

10.描述器

class Int:
    def __init__(self, name):
        print('init')
        self.name = name
    # __get__和__set__方法成对出现
    def __get__(self, instance, cls): # 访问属性时
        print('access')
        if instance is None:
            return self
        return instance.__dict__[self.name]
    
    def __set__(self, instance, value): # 修改属性时
        print('set')
        instance.__dict__[self.name] = value
        
    def __delete__(self, instance): # 删除属性时
        raise TypeError('not allowed')
# 用于控制对属性的访问、赋值和删除
class A:
    x = Int('x') # 实例化描述器,传入任意值填补Int.__init__的参数
    
    def __init__(self, x):
        self.x = x

11.描述器的应用

# property装饰器,把类方法改为类属性
class Property:
    def __init__(self, fget=None, fset=None, fdel=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
        print('initP')
        
    def __get__(self, instance, cls):
        print('get')
        if instance is None: # instance是调用Property实例方法的实例a
            return self
        if not callable(self.fget):
            raise AttributeError()
        return self.fget(instance) # self.fget即A.x
    
    def __set__(self, instance, value):
        print('set')
        if not callable(self.fset):
            raise AttributeError()
        self.fset(instance, value)
        
    def __delete__(self, instance):
        print('delete')
        if not callable(self.fdel):
            raise AttributeError()
        self.fdel(instance)
        
    def setter(self, fset):
        print('setter')
        #self.fset = fset
        return Property(self.fget, fset, self.fdel)
        
    def delete(self, fdel):
        print('delete')
        #self.fdel = fdel
        return Property(self.fget, self.fset, fdel)
        
    def print(self):
        print(self.fget)

class A:
    def __init__(self, x):
        print('init2')
        self.__x = x
        
    @Property # 传入x方法作为fget,实例化了类装饰器
    def x(self):
        print('x')
        return self.__x
    
    # x = Property(A.x)
    
    @x.setter
    def x(self, value):
        print('set_x')
        self.__x = value
    # x = x.setter(A.x) = Property(x.fget, A.x, x.del)
# classmethod装饰器
from functools import wraps, partial

class Classmethod:
    def __init__(self, method):
        wraps(method)(self)
        
    def __get__(self, instance, cls):
        return partial(self.__wrapped__, cls)

class C:
    @Classmethod
    def method(cls):
        print(cls)
        
    @Classmethod
    def method2(cls, x):
        print(cls)
        print(x)
# 对类变量做类型检查
class Typed:
    def __init__(self, name, required_type):
        self.name = name
        self.required_type = required_type
        
    def __get__(self, instance, cls):
        if instance is None:
            return self
        return instance.__dict__[self.name]
    
    def __set__(self, instance, value):
        if not isinstance(value, self.required_type):
            raise TypeError(' {} required type {}'.format(self.name, self.required_type))
        instance.__dict__[self.name] = value
        
class A:
    x = Typed('x', int)
    y = Typed('y', str)
    
    def __init__(self, x, y):
        self.x = x
        self.y = y

 

© 著作权归作者所有

共有 人打赏支持
夏洛特_
粉丝 2
博文 80
码字总数 72279
作品 0
宁德
程序员
私信 提问
Supporting Python 3(支持python3)——使用现代的风格改善你的代码

使用现代风格改善你的代码 原文: http://python3porting.com/improving.html 译者: TheLover_Z 一旦你开始使用 Python 3,你就有机会接触新的特性来改善你的代码。这篇文章中提到的很多东西...

在湖闻樟
2015/10/26
0
0
搭个平台告诉你—Python基础分享

搭了个学习平台,有需要的来瞅瞅: Python简介 推荐:通过anaconda安装Python和主流第三方库 Python环境搭建 运行Python Python语句和语法 Python变量类型 if name == 'main'的含义 Python内...

MrLonelyZC88
10/24
0
0
zg手册 之 python2.7.7源码分析(1)-- python中的对象

源代码主要目录结构 Demo: python 的示例程序 Doc: 文档 Grammar: 用BNF的语法定义了Python的全部语法,提供给解析器使用 Include: 头文件,在用c/c++编写扩展模块时使用 Lib: Python自...

东昕
2014/07/08
0
0
Python基础入门教程(3)

人生苦短,我学Pyhton   Python(英语发音:/ˈpaɪθən/), 是一种面向对象、解释型计算机程序设计语言,由Guido van Rossum于1989年底发明,第一个公开发行版发行于1991年,Python 源代码同...

jamesjoshuasss
2017/03/06
0
0
最常见的 35 个 Python 面试题及答案(2018 版)

雷锋网按:本文为 AI 研习社编译的技术博客,原文 Top 35 Python Interview Questions and Answers in 2018 ,作者 DataFlair Team。 翻译 | 于志鹏 整理 | 凡江 1. Python 面试问题及答案 ...

雷锋字幕组
08/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

颜色模型与颜色应用---光的特性

电磁频谱 颜色的心理学特征

中国龙-扬科
21分钟前
2
0
android音频及强噪相关

Android AudioRecord和AudioTrack介绍(Android音频收集和播放 麦克风降噪) https://blog.csdn.net/tanningzhong/article/details/72844559 音频采集(AudioRecorder) https://www.jianshu.......

whoisliang
27分钟前
2
0
redis-持久化

RDB rdb持久化是把当前进程数据生成快照保存到磁盘的过程。触发RDB持久化过程分为手动触发和自动触发。 触发机制 bgsave执行流程 rdb优缺点 AOF 记录每次写命令,重启时再重新执行aof文件中的...

grace_233
32分钟前
3
0
电话激活Windows 中文操作系统步骤

已购买微软MAK批量授权,系统又在企业内网中,无法通过连接Internet进行激活,还可以通过电话完成激活。 前期准备 请提前准备好产品密钥,Product Key格式如下:XXXXX-XXXXX-XXXXX-XXXXX-XXX...

tonyfox
34分钟前
4
0
Apache用户认证,域名跳转,访问日志

Apache用户认证 当设置了用户认证后,用户访问网站时,需要输入用户名和密码才能访问。 可以全局设置,也可以为某几个虚拟主机单独配置。 下面以全局配置进行操作示例。 编辑httpd.conf进行配...

野雪球
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部