获取方法的名称
def test():
pass
print(test.__name__)
将当前文件的上级目录添加到环境变量中
import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)
上下文管理协议
with,as 都是上下文协议
class Open:
def __init__(self,name):
self.name = name
def __exit__(self, exc_type, exc_val, exc_tb):
print("____exit")
def __enter__(self):
print("____enter___")
return self
with Open("t.txt") as f:
print(f)
with obj as f等同于 f = f.enter()
- 如果有无异常的情况下 exc_type = NONE,exc_val =NONE,exc_tb = NONE
- 如果有异常如果返回false ,标示异常不处理
- 如果有异常并且返回True,标示处理异常
描述符
注意:被代理的属性,不纳入对象的属性字典中
数据描述符:实现了set和get方法
非数据描述符:没有set方法
描述符的优先级
-
类属性
-
数据描述符
-
实例属性
-
非数据描述符
-
找不到的属性凑发 getAttr
-
类型限制:
class Typed:
def __init__(self,key,expect_type):
self.key = key
self.expect_type = expect_type
def __get__(self, instance, value):
print("__get__")
return instance.__dict__[self.key]
# print(("instance %s, value %s" %(instance,value)))
def __set__(self, instance, value):
print("__set__")
if not isinstance(value,self.expect_type):
raise TypeError(" %s 类型符合 %" %(self.key,self.expect_type))
instance.__dict__[self.key] = value
# print(("instance %s, value %s" % (instance, value)))
def __delete__(self, instance):
print("__delete__")
instance.__dict__.pop(self.key)
# print("instance %s" %instance)
class Person :
name = Typed("name",str);
age = Typed("age",int);
def __init__(self,name,age,salary):
self.name = name # 被Typed代理了
self.age =age
self.salary = salary
f = Person("lily","11",222.2)
print(f.__dict__)
print(f.name)
del f.name
print(f.__dict__)
函数的装饰器模型
给test函数加上统计时间的功能
import time
def timer(fuc):
def wrapper():
start_time = time.time()
print("-------->")
fuc()
end_time = time.time()
print(end_time - start_time)
return wrapper
@timer #语法糖 test() = timer(test)
def test():
time.sleep(3)
print("========>")
test()
类的装饰器
装饰器= 高阶函数+函数嵌套+闭包
def typed(**kwargs):
def desc(obj):
print("======传递过来的类",obj)
for key,value in kwargs.items():
setattr(obj,key,value)
return obj
print("===========>传递的参数",kwargs)
return desc
@typed(name = "lily") #@desc = @type(name = "lily") obj = @desc(Foo)
class Foo:
pass
操作符与装饰器类共同使用
class Typed:
def __init__(self,type,expect_type):
self.type = type
self.expect_type= expect_type
def __set__(self, instance, value):
if type(value) != self.expect_type:
# if not isinstance(value,self.expect_type):
raise TypeError("%s不是需要的类型 %s" %(self.type,self.expect_type))
instance.__dict__[self.type] = value
def __get__(self, instance, owner):
print("======>get")
return instance.__dict__[self.type]
def __delete__(self, instance):
print("======>delete")
instance.__dict__.pop(self.type)
def addArgs(** kwargs):
def decorate(obj):
for key,value in kwargs.items():
print("key %s,value %s" %(key,value))
#setattr (obj,key,Typed(key,value) = obj.key = Type(key,value)
setattr(obj,key,Typed(key,value))
return obj
return decorate
@addArgs(name = str,age = int)
class Person:
#代理属性
# name = Typed("name",str)
# age = Typed("name", int)
def __init__(self,name,age,salay):
self.name = name
self.age = age
self.salay = salay
p = Person("lily","1",35.00)
del p.name
# print(p.name)
print(p.__dict__)
静态属性,类方法,静态方法
- 静态属性:可以让类对象调用函数属性如同调用数据属性一样
- 类方法:想访问类中的属性,但又不想和实例对象有关
- 静态方法:不想和类有关也不想和实例有关
class Room:
tag = 1
def __init__(self,name,width,lenght):
self.name = name
self.width = width
self.lenght= lenght
#静态属性
@property
def area(self):
return self.width*self.lenght
#类方法
@classmethod
def tell_info(cls):
print("=======>",cls)
print("=======>",cls.tag)
#静态方法
@staticmethod
def tell_something(a,b,c):
print("======>",a,b,c)
r = Room("202",10,20)
print(r.area)
Room.tell_info()
r.tell_something(1,2,3)
Room.tell_something(4,5,6)
利用描述符自定义property
class LazyProperty:
def __init__(self,func):
self.func = func
def __get__(self, instance, owner):
return self.func(instance)
class Room:
def __init__(self,name,width,length):
self.name = name
self.width = width
self.length = length
@LazyProperty #如果不带括号1. 类似执行 getArea = LazyProperty(getArea),这个也是一个描述符,如果带括号类似执行另外一个函数mothonA ,执行mothonA(getArea),
def getArea(self):
return self.width*self.length
r = Room("302",10,2)
print(r.getArea) #r.getArea,调用描述符的 __get__方法
自定义property延迟计算功能
延迟计算是指相同的计算函数不能反复执行,例如求面积只是求一次,后面用相同的就可以了,采用原理是将前一次计算的函数保存到对象的字典中,下次计算的时候直接拿来用就行了。
只是注意操作符的优先级就行了
class LazyProperty:
def __init__(self,func):
self.func = func
def __get__(self, instance, owner):
if instance is None:
return self
res = self.func(instance)
setattr(instance,self.func.__name__,res)
return self.func(instance)
class Room:
def __init__(self,name,width,length):
self.name = name
self.width = width
self.length = length
@LazyProperty
def getArea(self):
return self.width*self.length
r = Room("2020",20,12)
print(r.getArea)
print(r.getArea)
自定义classmothod
class Lazyclassmothod:
def __init__(self,func):
self.func = func
def __get__(self, instance, owner):
print("====>",instance.__class__)
return self.func(instance.__class__)
class TestRoom:
tag = "我是testRoom"
def __init__(self,name):
self.name = name
@Lazyclassmothod #getTag = Lazyclassmothod(getTag)
def getTag(cls):
return cls.tag
r = TestRoom("202")
print(r.getTag)
自定义staticmonthod
class Lazystaticmonthod:
def __init__(self,func):
self.func = func
# self.kwargs = kwargs
def __get__(self, instance, owner):
return self.func
class Room :
def __init__(self,width,length):
self.width = width
self.length = length
@Lazystaticmonthod
def area(a,b,c,d):
print ("======>",a,b,c,d)
r =Room(1,3)
print(r.area(1,2,3,4))
Room.area(5,6,7,8)
property的其他用法
class Room:
def __init__(self,size):
self.size = size
@property
def AAA(self):
return self.size
@AAA.setter
def AAA(self,value):
print("==========set")
@AAA.deleter
def AAA(self):
print("==========>del")
r = Room(100)
print(r.size)
r.size = 2000
print(r.size)
del r.size
print(r.size)
网友评论