内置方法

#!/usr/bin/env python
# -*- coding:utf-8 -*-

 四个方法的使用演示

class BlackMedium:
    feature = 'Ugly'
    def __init__(self,name,addr):
        self.name = name
        self.addr = addr

    def sell_hours(self):
        print("%s 不傻" %self.name)

    def ren_hours(self):
        print("%s 不租" %self.addr)

b1 = BlackMedium('金三角','锦绣华城')
# 判断类b1 中是否有一个name字符串对应的方法或属性
print(hasattr(b1,'addr',))
# 判断类b1 中是否有一个ren_hours字符串对应的方法或属性
print(hasattr(b1,'ren_hours'))

# 获取属性
n = getattr(b1,'name')
print(n)
m = getattr(b1,'sell_hours')
m()

#设置属性
setattr(b1,'sb',True)
setattr(b1,'show_name',lambda self:self.name+'sb')
print(b1.__dict__)
print(b1.show_name(b1))

# 删除属性

delattr(b1,'addr')
delattr(b1,'show_name')
# delattr(b1,'show_name1111')#不存在,就报错
print(b1.__dict__)

******类也是对象*******





class Foo(object):
    staticField = 'oldboy'
    def __init__(self):
        self.name = 'wupeiqi'

    def func(self):
        return 'func'

    @staticmethod
    def bar():
        return 'bar'

print(getattr(Foo,'staticField'))
print(getattr(Foo,'func'))
print(getattr(Foo,'bar'))



反射当前模块成员

import sys
def s1():
    print('s1')

def f2():
    print('s2')

this_module = sys.modules[__name__]

a = hasattr(this_module,'s1')
b = hasattr(this_module,'s2')
print(a)
print(b)

三__setattr__,__delattr__,__getattr__



class Foo:
    x = 1
    def __init__(self,y):
        self.y = y

    def __getattr__(self, item):
        print('-->from getattr:你找的属性不存在:')

    def __setattr__(self, key, value):
        print('--> from setattr')
        # self.key = value
        # self.__dict__[key] = value

    def __delattr__(self, item):
        print('--> from delattr')
        # del self.item
        self.__dict__.pop(item)


property

四,二次加工标准类型(包装)


基于继承实现



class List(list):
    
    def append(self, p_object):
        if not isinstance(p_object,int):
            raise TypeError('must be int')

        super().append(p_object)

    @property
    def mid(self):
        index = len(self)//2
        return self[index]
l = List([1,2,3,4])
print(l)
l.append(5)
print(l)
print(l.mid)
l.insert(1,-123)
print(l)
print(len(l))
l.clear()
print(l)

# 练习,(clear 加权限限制)


class List(list):
    def __init__(self,item,tag = False):
        super().__init__(item)
        self.tag = tag

    def append(self, p_object):
        if not isinstance(p_object, int):
            raise TypeError

        super().append(p_object)

    def clear(self):
        if not self.tag:
            raise PermissionError
        super().clear()

l = List([1,2,3],False)
print(l)
print(l.tag)

l.append(123)
print(l)
l.tag = True
print(l.tag)
l.clear()
print(l)

# ***授权***


实现授权的关键点就是覆盖__getattr__方法

import time
class FileHandle:
    def __init__(self,filename,mode = 'r',encoding = 'utf-8'):
        self.file = open(filename,mode,encoding='utf-8')

    def write(self,line):
        t = time.strftime('%Y-%m-%d %T')
        self.file.write('%s %s '%(t,line))

    def __getattr__(self, item):
        return getattr(self.file,item)
f1 = FileHandle('b.txt','w+')
f1.write('你好啊')
f1.seek(10)
print(f1.read())
f1.close()


# 授权示范二



# __author__ = 'linhaifeng'
# 我们来加上b模式支持
"""
import time
class FileHandle:
    def __init__(self,filename,mode = 'r',encoding = 'utf-8'):
        if 'b' in mode:
            self.file = open(filename,mode)
        else:
            self.file == open(filename,mode,encoding= encoding)
        self.filename = filename
        self.mode = mode
        self.encoding = encoding

    def wriet(self,line):
        if 'b' in self.mode:
            if not isinstance(line,bytes):
                raise TypeError('must be bytes')
        self.file.write(line)

    def __getattr__(self, item):
        return getattr(self.file,item)

    def __str__(self):
        if 'b' in self.mode:
            res = "<_io.BufferedReadr name ='%s'>"%self.filename

        else:
            res = "<_io Text|OWrapper name = '%s' mode = '%s' encoding = '%s'>" %(self.filename,self.mode,self.encoding)
        return res

f1 = FileHandle('b.txt','wb')
f1.wriet("你好啊".encode('utf-8'))
print(f1)
f1.close()


# 练习题(授权)
# 练习一
"""
class List:
def __int__(self,seq):

self.seq = seq

def append(self,p_object):
if not isinstance(p_object,int):
raise TypeError('must be int')

self.seq.append(p_object)

@property
def mid(self):
index = len(self.seq)//2
return self.seq[index]

def __getattr__(self, item):
return getattr(self.seq,item)

def __str__(self):
return str(self.seq)
l = List([1,2,3,4])
print(l)
l.append(4)
print(l)
print(l.mid)


"""

# 五、、__getattribute__
"""
class Foo:
def __init__(self,x):
self.x = x

def __getattr__(self, item):
print('执行的是我')
# return self.__dict__[item]

f1 = Foo(10)
print(f1.x)
f1.xxxxxxx#不存在的属性访问,触发__getattr__


# getattribute

class Foo:
def __init__(self,x):
self.x =x

def __getattribute__(self, item):
print("不管是否存在,我都会执行")

f1 = Foo(10)
f1.x
f1.xxxxx
"""


# 六 、描述符(__get__,__set__,__delete__)
# 1 描述符是什么:描述符本身就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,
# 这个也被称为描述符协议__get__():调用一个属性时,触发。__get__():为一个属性赋值时,触发。
# __delete__():采用del删除属性时,触发

# 定义一个描述符
"""
class Foo:
def __get__(self,instance,owner):
pass

def __set__(self,instance,value):
pass

def __delete__(self, instance):
pass
"""

# 2.描述符是干什么的:描述符的作用是用来代理另外一个类属性的(必须把描述符定义成这个类的类属性,不能定义到构造函数中)
"""
class Str:
def __get__(self, instance, owner):
print('Str 调用')

def __set__(self, instance, value):
print('Str 设置。。。')

def __delete__(self, instance):
print('Str 删除。。。')

class Int:
def __get__(self, instance, owner):
print('Int 调用')

def __set__(self, instance, value):
print('Int 设置。。。')

def __delete__(self, instance):
print('Int 删除。。。')

class People:
name = Str()
age = Int()
def __init__(self,name,age):
self.name = name
self.age = age

p1 = People('alex',18)

p1.name
p1.name = 'egon'
del p1.name

p1.age
p1.age = 18
del p1.age

print(p1.__dict__)
print(People.__dict__)

print(type(p1) == People)#type(obj)其实是查看obj是由哪个类实例化来的
print(type(p1).__dict__ == People.__dict__)

"""

# 修订__get__方法
"""
class Str:
def __init__(self,name):
self.name = name

def __get__(self,instance,owner):
print("get-->",instance,owner)
if instance is None:
return self
return instance.__dict__[self.name]

def __set__(self, instance, value):
print("ste-->",instance,value)
instance.__dict__[self.name] = value

def __delete__(self, instance):
print('__delete__-->',instance)
instance.__dict__.pop(self.name)

class People:
name = Str('name')
def __init__(self,name,age,salary):
self.name = name
self.age = age
self.salary = salary

print(People.name)
"""

# 类的装饰器 :无
def decorate(cls):
print('类的装饰器开始运行了')
return cls
@decorate
class People:
def __init__(self,name,age,salary):#salary 薪水
self.name = name
self.age = age
self.salary = salary

p1 = People('alex',18,3000)


# 类的装饰器:无参
def Typeassert(**kwargs):
def decorate(cls):
print('类的装饰器开始运行了',kwargs)
return cls
return decorate

@Typeassert(name = atr,age = int,salary = float)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @property回顾
"""
class Room:
def __init__(self,name,width,length):
self.name = name
self.width = width
self.length = length

@property
def area(self):
return self.width * self.length

r1 = Room('alex',2,3)
print(r1.area)

"""
# 自己做一个@property
"""
class lazyproperty:
def __init__(self,func):
self.func = func

def __get__(self, instance, owner):
print('这是我自己制定的静态属性,r1.area 实际上是要执行 r1.area()')
if instance is owner:
return self
return self.func(instance)

class Room:
def __init__(self,name,width,length):
self.name = name
self.width = width
self.length = length

@lazyproperty
def area(self):
return self.width * self.length

r1 = Room('alex',2,3)
print(r1.area)

"""
# 实现延迟计算功能
"""
class Lazyproperty:
def __init__(self,func):
self.func = func

def __get__(self, instance, owner):
print("这是自己定制的静态属性,r1.area 实际上是要执行r1.area()")
if instance is None:
return self
else:
print("-->")
value = self.func(instance)
setattr(instance,self.func.__name__,value)
return value

class Room:
def __init__(self,name,width,length):
self.name = name
self.width = width
self.length = length

@Lazyproperty #area = Lazyproperty(area) 相当于定义了一个类属性,即描述符
def area(self):
return self.width * self.length

r1 = Room('ouayng',2,3)
print(r1.area)
print(r1.area)
"""

# 六 再看property
# 一个静态属性property本质就是实现了get,set,delete 三种方法

# 用法一:

"""
class Foo:
@property
def BBB(self):
print("get 的时候运行")

@BBB.setter
def BBB(self,value):
print("set 的时候运行")

@BBB.deleter
def BBB(self):
print("delter 的时候运行")

# 只有在属性BBB定义property之后才能定义BBB.setter,BBB.deleter

f1 = Foo()
f1.BBB
f1.BBB = 'aaa'
del f1.BBB

"""


# 用法二
"""
class Foo:
def get_BBB(self):
print("get 的时候运行")

def set_BBB(self, value):
print("set 的时候运行")

def deleter_BBB(self):
print("delter 的时候运行")
BBB = property(get_BBB,set_BBB,deleter_BBB)

f1 = Foo()
f1.BBB
f1.BBB = 'aaa'
del f1.BBB

"""

# 怎么用
# ******案例一*******
"""
class Goods:
def __init__(self):
self.original_price = 100
self.discount = 0.8

def get_price(self):
new_price = self.original_price * self.discount
return new_price

def set_pricce(self,value):
self.original_price = value

def deleter_price(self):
del self.original_price

price = property(get_price,set_pricce,deleter_price)
obj = Goods()
obj.get_price
obj.price = 80
print(obj.price)
del obj.price
"""
# 从写案例一
"""
class Goods:
def __init__(self):
self.original_price = 100
self.discount = 0.8

@property
def price(self):
new_price = self.original_price * self.discount
return new_price

@price.setter
def price(self,value):
self.original_price = value

@price.deleter
def deleter(self):
del self.original_price

obj = Goods()

yj = obj.original_price
print(yj)
obj.price
obj.price = 20
print(obj.price)
obj.deleter
print(obj.deleter)
"""

# *****案例二******
# 实现类型检测功能

# 第一关
# class People:
# def __init__(self,name):
# self.name = name
#
# @property
# def name(self):
# return self.name

# 第二关:修订版
"""
class People:
def __init__(self,name):
self.name = name# 实例化就触发property


@property
def name(self):
# return self.name 无限递归
print('get--->')
return self.DouNiWan

@name.setter
def name(self,value):
print('set-->')
self.DouNiWan = value

@name.deleter
def name(self):
print('delete-->')
del self.DouNiWan
p1 = People('alex')
print(p1.name)
# print(p1.name)
# print(p1.name)
print(p1.__dict__)

p1.name = 'egon'
print(p1.__dict__)

del p1.name
print(p1.__dict__)

"""

# 七、 __setitem__,__getitem__,__delitem__
"""
class Foo:
def __init__(self,name):
self.name = name

def __getitem__(self, item):
print(self.__dict__[item])

def __setitem__(self, key, value):
self.__dict__[key] = value

def __delitem__(self, key):
print('del obj[key]时,我执行')
self.__dict__.pop(key)

def __delattr__(self, item):
print('del obj.key 时,我执行')
self.__dict__.pop(item)

f1 = Foo('sb')
f1['age'] = 18
f1["age1"] = 19
del f1.age1
del f1['age']
f1['name'] = 'alex'
print(f1.__dict__)

"""

# 八、__str__,__repr__,__format__
# 改变对象的字符串显示 __str__,__repr__
# 自定制格式化字符串__format__
"""
__author__ = 'linhaifeng'
format_dic = [
'nat':'{obj.name}-{obj.addr}-{obj.type}'
'tna':''
]
"""


# 九、 slots
# 1,含义:__slots__是一个类变量,变量值可以是列表,元组,或者可迭代对象,也可以是一个字符串
# 2、引子、使用点来访问属性本质就是在访问类或者对象的__dict__属性字典(类的字典是共享的,每个实例是独立的)
# __slots__会为实例使用一种更加紧凑的内部表示,很多特性都依赖于字典,
# 常见误区:它可以作为一个封装工具来防止用户给实例增加新的属性
# 简而言之,__slots__就是一个字典,只能被付一次值
"""
class Foo:
__slots__ = 'x'

f1 = Foo()
f1.x = 1
f1.x = 2#报错
f1.x = 3
print(f1.__slots__)

"""
"""
class Bar:
__slots__ = ['x','y']

n = Bar()
n.x,n.y = 1,2
# n.z = 3
print(n.__slots__)

"""

# 刨根问底
"""
class Foo:
__slots__ = ['name','age']

f1 = Foo()
f1,name = 'alex'
f1.age = 18
print(f1.__slots__)

f2 = Foo()
f2.name = 'egon'
f2.age = '19'
print(f2.__slots__)

print(Foo.__slots__)
f1,f2都会报错,f1,f2都没有属性字典__dict__了,统一归__slots__管,节省内存。

"""

# 十、__next__和__iter__ 实现迭代器协议

# 简单示范
"""
import time
class Foo:
def __init__(self,x):
self.x =x

def __iter__(self):
return self

def __next__(self):
n = self.x
self.x += 1
return self.x

f1 = Foo(3)
for i in f1:
print(i)
time.sleep(1)
"""


"""

class Foo:
def __init__(self,start,stop):
self.num = start
self.stop = stop


def __iter__(self):
return self

def __next__(self):
if self.num >= self.stop:
raise StopIteration

n = self.num
self.num += 1
return n

f = Foo(1,5)
from collections import Iterable,Iterator
print(isinstance(f,Iterator))

for i in Foo(1,5):
print(i)
"""

# 练习:简单模拟range,加上步长
"""
class Range:
def __init__(self,n,stop,step):
self.n = n
self.stop = stop
self.step = step

def __next__(self):
if self.n >= self.stop:
raise StopIteration
x = self.n
self.n += self.step
return x

def __iter__(self):
return self

for i in Range(1,7,3):
print(i)

"""
# 斐波那契数列
"""
class Fib:
def __iter__(self):
self._a = 0
self._b = 1

def __iter__(self):
return self

def __next__(self):
self._a,self._b = self._b,self._a + self._b
return self._a

f1 = Fib()

print(f1.__next__())
print(next(f1))
print(next(f1))

for i in f1:
if i > 100:
break

print('%s' %i,end='')

"""

# 十一、__doc__
"""
# 它类的描述信息

class Foo:
print('我是描述信息')
pass

print(Foo.__doc__)

# 该属性无法被继承
class Foo:
print('我是描述信息')
pass

class Bar(Foo):
print('我是子类')
pass
print(Bar.__doc__)#该属性无法继承子类
"""




# 十二、__module__ ,__class__
# __module__表示当前操作的对象在那个模块
# __class__ 表示当前操作的对象的类是什么


# 十三、__del__
# 清楚对象的同时回收系统资源,用到__del__
"""
class Foo:
def __del__(self):
print('执行我了')


f1 = Foo()

del f1#这时会执行def __del__(self) 内容
print("------->")

"""
# 十四,__enter__, __exit__

"""
class Open:
def __init__(self,name):
self.name = name

def __enter__(self):
print('出现with 语句 ,对象的__enter__被触发,有返回值则赋值给as 声明的变量')
return self

def __exit__(self, exc_type, exc_val, exc_tb):
print('with 中代码块执行完毕时执行我啊')


with Open('a.txt') as f:
print('执行代码块')
print(f,f.name)
"""
#__exit__() 中的 三个参数分别代表异常类型,异常值,和追溯信息,with 语句中的代码块出现异常
# ,则with 后代码都无法执行
"""
class Open:
def __init__(self,name):
self.name = name

def __enter__(self):
print("出现with 语句,对象的__enter__被触发,有返回值则赋值给as 声明的变量")

def __exit__(self, exc_type, exc_val, exc_tb):
print('with 中的代码执行完毕')
print(exc_type)
print(exc_val)
print(exc_tb)

with Open('a.txt') as f:
print('=====>执行代码块')
raise AttributeError('***着火了,救火了****')

print('0'*100)#不会执行

"""

# 十五、__call__
# 对象后加括号,触发执行
# 注:构造方法的执行是由创建对象触发的,即:对象 = 类名():
# 而对于__call__方法的执行是由对象后加括号触发的,即 对象()或者 类()()

"""
class Foo:
def __init__(self):
pass

def __call__(self, *args, **kwargs):
print("类后面加上俩括号会执行__call__")

print('__call__')

# obj = Foo()
# obj()
Foo()()

"""















原文地址:https://www.cnblogs.com/ouyang99-/p/9077330.html