文档章节

Python3类

夏洛特_
 夏洛特_
发布于 2016/11/03 19:23
字数 1774
阅读 12
收藏 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)——语言区别和暂时解决方法

语言区别和暂时解决方法 这个附录包含一个Python 2和Python 3的不同之处列表以及能不用2to3转换同时在Python 2和Python 3下运行的示例代码。 这个列表是不完整的。在这里列出的只有不包括bug...

在湖闻樟
2015/11/20
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
Supporting Python 3(支持python3)——使用现代的风格改善你的代码

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

在湖闻樟
2015/10/26
0
0
简单比较Python的数据持久化操作

转自http://smartzxy.iteye.com/blog/680431 简单比较Python的数据持久化操作(一) 最近喜欢上了Python,喜欢它的简洁高效,喜欢它的“无所不能”。 Python的数据持久化操作主要是六类:普通...

alazyer
2014/05/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot 使用parent方式引用时 获取值属性方式默认@

采用官网提供的 引入依赖时,application.properties中的值变量,无法通过${}获取,这是由于Spring Boot 已经将字符方式调整为 <resource.delimiter>@</resource.delimiter>。故如果在,工程中...

翱翔fly
15分钟前
1
0
HTTPS证书验证流程及SSL证书生成步骤【附nginx开启https配置】

------------------------------------------------------------ HTTPS证书验证流程(极简化版) 1.客户端向服务端请求证书(server.crt) 2.服务端下发证书(server.crt) 3.客户端用预制的...

xiaomin0322
16分钟前
1
0
预编译sql语句和参数化sql能有效防止——sql注入攻击——

预编译和参数化处理sql原理类似: 参数化处理sql 是将参数进行了字符串化处理,把参数中的单引号,井号#,等都做了转义处理,进而在执行sql语句时不会被当做sql中的定界符和指定符来执行。 ...

fang_faye
17分钟前
1
0
springboot最全配置解释

​​​​​​​# ----------------------------------------# 核心属性# ----------------------------------------# 文件编码banner.charset= UTF-8# 文件位置banner.locati...

废柴大叔
18分钟前
72
1
(大致了解下)从单机到2000万QPS: 知乎Redis平台发展与演进之路

导读:知乎存储平台团队基于开源Redis 组件打造的知乎 Redis 平台,经过不断的研发迭代,目前已经形成了一整套完整自动化运维服务体系,提供很多强大的功能。本文作者是是该系统的负责人,文...

Ocean_K
25分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部