文档章节

Python3类

夏洛特_
 夏洛特_
发布于 2016/11/03 19:23
字数 1774
阅读 6
收藏 0
点赞 0
评论 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
博文 79
码字总数 70749
作品 0
宁德
程序员
Python与C#对比 python学习

Python是一种跨平台语言。无论是在Windows、Linux、Unix还是Mac Os系统,我们都可以使用Python。甚至在Linux、Unix及Mac OS系统内已经集成了Python。语法简洁优美, 简单,易学。拥有强大的标...

zhouzhou2018 ⋅ 05/23 ⋅ 0

用MaxCompute Studio开发Python UDF(附采坑记录)

1.环境 系统:MacOS 系统自带Python版本(/usr/bin/python):2.7.10 Anaconda Python版本:2.7.14 Maxcompute Studio版本: 2.9.1 2.安装Python|Pyodps|Python插件 MaxCompute studio能支持用......

watercat ⋅ 05/24 ⋅ 0

Python是面向对象的语言吗?python编程

  Python虽然是解释型语言,但从设计之初就已经是一门面向对象的语言,对于Python来说一切皆为对象。正因为如此,在Python中创建一个类和对象是很容易的,当然如果习惯面向过程或者函数的写...

老男孩Linux培训 ⋅ 06/08 ⋅ 0

1. Python3源码—内建对象

1.1. Python内的对象 Python中的类和实例都是通过Python内的对象来实现的。Python中已经预先定义了一些类型对象。这些内建类型对象通过实例化,可以创建内建类型对象的实例对象。 在Python中...

whj0709 ⋅ 06/06 ⋅ 0

python3.x与python2.x的区别汇总

python3.x与python2.7.x都是比较流行的版本,虽然建议现在的初学者开始学习python3.x的版本,但是还有很多的工程使用的是python2.7.x版本。观看代码的时候难免会出现一些问题。 在google上搜...

oldpan ⋅ 2017/10/10 ⋅ 0

云计算培训学院,云计算Python自动化运维开发实战

都忘记是什么时候知道python的了,我是搞linux运维的,早先只是知道搞运维必须会shell,要做一些运维自动化的工作,比如实现一些定时备份数据啊、批量执行某个操作啊、写写监控脚本什么的。后...

长沙千锋 ⋅ 05/15 ⋅ 0

为什么python突然变得这么火了?

可能会有一种感觉python突然之间变得这么火热了,个人感觉还是雷声大雨点小,真正用pytho落地的东西还是少,不可否认的python前途无量,现在人工智能的调用框架选择了python。所以目前阶段选...

Python燕大侠 ⋅ 05/10 ⋅ 0

王老板Python面试(10):17道python笔试面试真题

1、一行代码实现1--100之和 利用sum()函数求和 2、如何在一个函数内部修改全局变量 利用global 修改全局变量 3、列出5个python标准库 os:提供了不少与操作系统相关联的函数 sys: 通常用于命...

程序员八阿哥 ⋅ 05/22 ⋅ 0

Python(1)——python安装和第一个程序

/============================ 以下所有内容,均来自 廖雪峰 的官方网站, python 教程。 链接地址:http://www.liaoxuefeng.com ============================/ python 简介 1、python 是一...

docallen ⋅ 2017/04/25 ⋅ 0

5本必读Python入门书籍,你都看过吗?(附福利)

今天技术学派为大家准备了5本Python入门书籍,除了书籍小编还整理了3个常用的资源网站分享给大家。 1.Python基础教程 《Python基础教程》是经典的Python入门教程书籍,本书层次鲜明,结构严谨...

Python燕大侠 ⋅ 06/07 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

idea 整合 vue 启动

刚学习Vue 搭建了一个项目 只能命令启动 Idea里面不会启动 尝试了一下修改启动的配置 如下: 1.首先你要保证你的package.json没有修改过 具体原因没有看 因为我改了这个name的值 就没办法启动...

事儿爹 ⋅ 28分钟前 ⋅ 0

数据仓库技术概述(一看就是架构师写的,对我极其有用)

ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract)、交互转换(transform)、加载(load)至目的端的过程。ETL一词较常用在数据仓库,但其对象并不限于...

gulf ⋅ 29分钟前 ⋅ 0

redis在windows环境的后台运行方法

在后台运行,首先需要安装redis服务,命令为 redis-server.exe --service-install redis.windows.conf --loglevel verbose 启动,命令为 redis-server --service-start 停止,命令为 redis-...

程序羊 ⋅ 31分钟前 ⋅ 0

比特币现金开发者提出新的交易订单规则

本周,四位比特币现金的四位开发者和研究员:Joannes Vermorel(Lokad),AmaurySéchet(比特币ABC),Shammah Chancellor(比特币ABC)和Tomas van der Wansem(Bitcrust)共同发表了一篇关...

lpy411 ⋅ 35分钟前 ⋅ 0

vue获取input输入框的数据

用惯了jQuery,突然使用vue感觉很不习惯,有很多不同的地方,感觉是两个不同的思想来写前端的代码。jQuery是使用选择器($)选取DOM对象,对其进行赋值、取值、事件绑定等操作。而Vue则是通过...

王子城 ⋅ 37分钟前 ⋅ 0

竟然这就是面向对象的游戏设计?!

从程序角度考虑,许多 JavaScript 都基于循环和大量的 if/else 语句。在本文中,我们可了解一种更聪明的做法 — 在 JavaScript 游戏中使用面向对象来设计。本文将概述原型继承和使用 JavaSc...

柳猫 ⋅ 42分钟前 ⋅ 2

git cmd git bash

刚用到了Git,看到windows环境下有两个命令输入窗口 第一个是可视化图形界面,第二个是CMD,第三个是Bash。 Git中的Bash是基于CMD的,在CMD的基础上增添一些新的命令与功能。所以建议在使用的...

东东笔记 ⋅ 44分钟前 ⋅ 0

分布式系统CAP和Base

1、分布式系统 1.1 简介 由多台计算机和通信的软件组件通过计算机网络连接(本地网络或广域网)组成。分布式系统是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的...

xixingzhe ⋅ 55分钟前 ⋅ 0

查看磁盘占用情况

记一次jenkins构建失败的问题 Build step 'Send build artifacts over SSH' changed build result to UNSTABLE 网上查资料都没明确表明是什么错,回忆之前处理这样的问题。第一时间想到的是不...

ManderSF ⋅ 56分钟前 ⋅ 0

数据库管理提速:SQL解析的探索与应用

前言: SQL解析是一项复杂的技术,一般都是由数据库厂商来掌握,当然也有公司专门提供SQL解析的API。SQL解析与优化是属于编译器范畴,和C语言等其他语言的解析没有本质的区别。其中分为词法分...

java高级架构牛人 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部