# 1.知识点:深浅拷贝的区别(尝试通过id来验证判断)?
# import copy
# l = [1,2,[11,22]]
# l1 = copy.copy(l) # 浅拷贝
# l2 = copy.deepcopy(l) # 深拷贝
# l.append(666)
# print(l1,l2) # [1, 2, [11, 22]] [1, 2, [11, 22]]
# l[2].append(666)
# print(l1,l2) # [1, 2, [11, 22, 666]] [1, 2, [11, 22]]
# from decimal import Decimal
# 2.format、decimal你真的懂它吗?
# a = 3.1
# b = 4.2
# c = a + b
# print(c)
#
# print(format(c,'e'))
# print(format(c,'0.2f'))
# print(format(c,'E'))
# print(bin(10))
# print(oct(10))
# print(hex(10))
# print(format(0b1010,'b'))
# print(format(0o12,'o'))
# print(format(0xa,'x'))
"""
3.求下列列表的前三名和后三名
nums=[1,3,5,65,-9,23,45,0]
打印下列薪资前两名的字典
dic=[
{'name':'Tom','salary':2000},
{'name':'Tony','salary':2333},
{'name':'Hoowk','salary':4000},
{'name':'Mr3','salary':1000}
]
"""
#
#
# import heapq
# nums=[1,3,5,65,-9,23,45,0]
# print(heapq.nlargest(4,nums))
# print(heapq.nsmallest(4,nums))
#
# dic=[
# {'name':'Tom','salary':2000},
# {'name':'Tony','salary':2333},
# {'name':'Hoowk','salary':4000},
# {'name':'Mr3','salary':1000}
# ]
# print(heapq.nlargest(3,dic,lambda x:x['salary']))
# 4.正常情况下,当我们定义了一个class,创建了一个class的实例后,
# 我们可以给该实例绑定任何属性和方法。但是,如果我们想要限制实例的属性怎么办?
# class People(object):
# __slots__ = ["name","age"]
# def __init__(self,name,age,score):
# self.name = name
# self.age = age
# self.score = score
#
# obj = People('egon',18,90)
5.什么是函数,什么是方法?
# from types import MethodType,FunctionType
# class Demo(object):
#
# def foo(self):
# pass
#
# # 第一种
# obj = Demo()
# obj.foo()
# print(isinstance(obj.foo,MethodType)) # True
# print(isinstance(obj.foo,FunctionType)) # False
#
# # 第二种
# Demo.foo('123')
# print(isinstance(Demo.foo,MethodType)) # False
# print(isinstance(Demo.foo,FunctionType)) # True
# 6.用面向对象的知识编写实现range的功能
# print([i for i in range(10)])
# class My_range(object):
#
# def __init__(self,start,stop):
# self.start = start
# self.stop = stop
#
# def __iter__(self):
# while self.start < self.stop:
# yield self.start
# self.start += 1
#
# def __reversed__(self):
# while self.stop > self.start:
# yield self.stop
# self.stop -= 1
#
# # for i in My_range(1,10):
# # print(i)
#
# for i in reversed(My_range(1,10)):
# print(i)
反射
hassttr
setattr
delattr
删除原有方法时delattr(Student,'study')
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)
#__setattr__添加/修改属性会触发它的执行
f1=Foo(10)
print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
f1.z=3
print(f1.__dict__)
#__delattr__删除属性的时候会触发
f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
del f1.a
print(f1.__dict__)
#__getattr__只有在使用点调用属性且属性不存在的时候才会触发
f1.xxxxxx
slots__是什么:是一个类变量,变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性)
2.引子:使用点来访问属性本质就是在访问类或者对象的__dict__属性字典(类的字典是共享的,而每个实例的是独立的)
3.为何使用__slots__:字典会占用大量内存,如果你有一个属性很少的类,但是有很多实例,为了节省内存可以使用__slots__取代实例的__dict__
当你定义__slots__后,__slots__就会为实例使用一种更加紧凑的内部表示。实例通过一个很小的固定大小的数组来构建,而不是为每个实例定义一个
字典,这跟元组或列表很类似。在__slots__中列出的属性名在内部被映射到这个数组的指定小标上。使用__slots__一个不好的地方就是我们不能再给
实例添加新的属性了,只能使用在__slots__中定义的那些属性名。
4.注意事项:__slots__的很多特性都依赖于普通的基于字典的实现。另外,定义了__slots__后的类不再 支持一些普通类特性了,比如多继承。大多数情况下,你应该
只在那些经常被使用到 的用作数据结构的类上定义__slots__比如在程序中需要创建某个类的几百万个实例对象 。
关于__slots__的一个常见误区是它可以作为一个封装工具来防止用户给实例增加新的属性。尽管使用__slots__可以达到这样的目的,但是这个并不是它的初衷。 更多的是用来作为一个内存优化工具。
'''
class Foo:
__slots__='x'
f1=Foo()
f1.x=1
f1.y=2#报错
print(f1.__slots__) #f1不再有__dict__
class Bar:
__slots__=['x','y']
n=Bar()
n.x,n.y=1,2
n.z=3#报错
import abc #利用abc模块实现抽象类
class All_file(metaclass=abc.ABCMeta):
all_type='file'
@abc.abstractmethod #定义抽象方法,无需实现功能
def read(self):
'子类必须定义读功能'
pass
@abc.abstractmethod #定义抽象方法,无需实现功能
def write(self):
'子类必须定义写功能'
pass