Python 面向对象进阶(二)
1. 垃圾回收
- 小整数对象池
- Python对小整数的定义是
[-5, 257)
,这些整数对象是提前建立好的; - 在一个Python程序中,所有位于这个范围内的整数,使用的都是同一个对象;
- 单个字符共用对象,常驻内存;
- Python对小整数的定义是
- 大整数对象池
- 每一个大整数,均创建一个新的对象;
intern
机制- 单个单词,不可修改,默认开启intern机制,共用对象,当引用计数为0时,则销毁;
- 字符串(含有空格),不可修改,没有开启intern机制,不共用对象;
# 示例:
a1 = "Helloworld"
a2 = "HelloWorld"
a3 = "HelloWorld"
a4 = "HelloWorld"
a5 = "HelloWorld"
a6 = "HelloWorld"
# 说明:
# intern 机制,内存中只有一个"HelloWorld"所占的空间,靠引用计数去维护何时释放。
1.1 GC 垃圾回收
- Python 采用的是引用计数机制为主,以分代收集机制为辅的策略;
- gc 模块常用函数:
gc.get_threshold()
: 获取gc模块中自动执行垃圾回收的频率;gc.set_threshold(threshold[, threshold1[, threshold2]])
设置自动执行垃圾回收的频率;gc.get_count()
: 获取当前自动执行垃圾回收的计数器,返回一个长度为3的列表;gc.collect()
: 显示执行垃圾回收;
# 示例:
# 引用计数缺点:循环引用
class ClassA():
def __init__(self):
print("object born,id:%s" % str(hex(id(self))))
def f2():
while True():
c1 = ClassA()
c2 = ClassA()
c1.t = c2
c2.t = c1
del c1
del c2
f2()
2. 内建属性和内建函数
2.1 内建属性
- 常用属性
__init__
: 构造初始化函数;__new__
: 生成实例所需属性;__class__
: 实例所在的类,实例.__class__
__str__
:print(类实例)
自动调用对象的__str__
方法;__int__
:int(对象)
自动执行对象的__int__
方法,并将返回值赋给int对象;__repr__
: 实例字符串表示,准确性; 类实例 回车时触发__del__
:del 实例
时,触发;__dict__
: 将对象中封装的所有内容通过字典的形式返回;__doc__
: 类文档,子类不继承;help(类或实例)
__getattribute__
: 属性访问拦截器;__bases__
: 类的所有父类构成元素,类名.__bases__
# 示例: 属性拦截器
class Test(object):
def __init__(self, subject1):
self.subject1 = subject1
self.subject2 = 'cpp'
# 属性访问拦截器,打印日志信息
def __getattribute__(self, obj):
print("===1>%s" % obj)
if obj == 'subject1':
print('log subject1')
return 'redicrect python'
else:
temp = object.__getattribute__(self, obj)
print("===2>%s" % str(temp))
return temp
def show(self):
print("this is a Test")
s = Test("python")
print(s.subject1)
print(s.subject2)
s.show()
# 调用方法步骤:
# 1. 先使用属性访问拦截器,获取show属性对应的方法;
# 2. 方法()
# 示例二: 属性拦截器注意事项
class Person(object):
def __getattribute__(self, obj):
print("=== test ===")
if obj.startswith("a"):
return "haha"
else:
return self.test
def test(self):
print("heihei")
t = Person()
t.a # 返回 haha
t.b # 会让程序挂掉
# 原因: 当 t.b 执行时,会调用Person类中定义的 __getattribute__ 方法, if 条件不满足,所以程序
# 执行 else 里面的代码, 即 return self.test; 因为 return 需要 self.test 的值返回,那么首先
# 要先获取 self.test 的值, 因为 self 此时就是对象 t, 所以,self.test = t.test, t.test 此时
# 要获取t这个对象的 test 属性,那么,就会跳转到 __getattribute__ 方法去执行,即此时产生了递归调用;
# 示例三: __getitem__
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
def __getitem__(self, item):
return item + 10
def __setitem__(self, key, value):
print(key, value)
def __delitem__(self, key):
print(key)
li = Foo('zhangsan', 18)
a = li[8] # 此处,会自动执行li对象的的 __getitem__ 方法, 8 会当作参数传递给 item
print(a)
li[100] = 'master' # 会调用 __setitem__ 方法
del li[666] # 会调用 __delitem__ 方法
# 示例四: __iter__
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
def __iter__(self):
return iter([11, 22, 33])
li = Foo('alex', 19)
for i in li:
# 1. 执行li对象对应的类 Foo 中的 __iter__ 方法, 并获取其返回值
# 2. 循环上一步返回的对象
print(i)
# 备注:
# 1. 如果类中有 __iter__ 方法, 那么,该类生成的对象为可迭代对象;
# 2. 对象.__iter__() 返回值为迭代器;
# 示例五: __call__ 方法
class Foo:
def __init__:
pass
def __call__:
pass
obj = Foo() # 此处,会自动执行 __init__ 方法
obj() # 此处,会自动执行 __call__ 方法
2.2 内建函数
dir(__builtins__)
: 可以查看Python解释器启动后,默认加载的属性和函数;
# 示例一: range
range(stop)
range(start, stop[, step])
# 备注:
# python2中 range 返回列表;
# python3中 range 返回一个迭代值;如果想得到列表,可通过 list 函数
# pyton3 创建列表的另外一种方法:
testList = [x*2 for x in range(10)]
testList
# 示例二: map 函数
# map 函数会根据提供的函数对指定序列做映射
# map(function, sequence[, sequence, ...]) -> list
# function: 函数
# sequence: 一个或多个序列,取决于function需要几个参数;
# 返回值是一个list
# 函数需要一个参数
map(lambda x: x*x, [1, 2, 3]) # 结果为: [1, 4, 9]
# 函数需要两个参数
map(lambda x, y: x+y, [1, 2, 3], [4, 5, 6]) # 结果为: [5, 7, 9]
# 示例三: filter 函数
# filter(function or None, sequence) -> list, tuple, or string
# function: 接受一个参数,返回布尔值True或False
# sequence: 序列可以是 str, tuple, list
# filter 函数会对序列参数sequence中的每个元素调用function函数, 最后返回的结果包含调用结果为
# True的元素
filter(lambda x: x%2, [1, 2, 3, 4]) # 结果为[1, 3]
# 示例四: reduce 函数
# reduce(function, sequence[, initial]) -> value
# function: 该函数有两个参数
# sequence: 序列可以是 str, tuple, list
# initial: 固定初始值
# reduce 函数依次从sequence中取一个元素,和上一次调用function的结果做参数再次调用function。第一次调用
# function时,如果提供initial参数,会以sequence中的第一个元素和initial作为参数调用function, 否则会以
# 序列sequence中的前两个元素做参数调用function。注意,function 函数不能为None
reduce(lambda x, y: x+y, [1, 2, 3, 4]) # 结果为: 10
reduce(lambda x, y: x+y, ['aa', 'bb', 'cc'], 'dd') # 结果为: ddaabbcc
# 备注: Python3, reduce函数已经从全局名字空间中移除,现在被放置在functools模块里面,
# 如果需要使用,需要先导入: from functools import reduce
# 示例五: sorted 函数
# sorted(iterable, cmp=None, key=None, reverse=Fale) -> new sorted list
sroted(['dd','yy','ee','ss','ww'], reverse=1)
3. 集合 set
- 集合与之前列表,元组类似,可以存储多个数据,但是这些数据是不重复的;
- 集合对象还支持union(联合), intersection(交), difference(差)和sysmmetric_difference(对称差集)等数学运算;
# 示例:
a = "abcdef"
b = set(a) # 输出: {'a', 'b', 'c', 'd', 'e', 'f'}
A = "bdfwm"
B = set(A)
b&B # 取交集
b|B # 取并集
b-B # 取差集
b^B # 对称差集(在b或B中,但不会同时出现在二者中)
4. functools
# Python3
import functools
dir(functools) # 查看所有的工具函数
# 函数一: partial函数(偏函数)
# 把一个函数的某些参数设置默认值,返回一个新的函数,调用这个新函数会更简单
import functools
def showarg(*args, **kw):
print(args)
print(kw)
p1 = functools.partial(showarg, 1,2,3)
p1() # 输出: (1, 2, 3) {}
p1(4, 5, 6) # 输出: (1, 2, 3, 4, 5, 6) {}
p1(a='python', b='java') #输出: (1, 2, 3) {'b':'java', 'a':'python'}
# 函数二: wraps 函数
# 使用装饰器时,有一些细节需要被注意。例如,被装饰后的函数,其实已经是另外一个函数了(函数属性会发生改变)
def note(func):
'''note function''' # 说明文档
def wrapper():
'''wrapper function'''
print('note something')
return func()
return wrapper
@note
def test():
'''test function'''
print('I am test')
print(help(test))
# 输出wrapper的说明文档
# wrapper()
# wrapper function
# functools 包提供了 wraps 装饰器来消除这样的副作用
import functools
def note(func):
'''note function'''
@functools.wraps(func)
def wrapper():
'''wrapper function'''
print('note something')
return func()
return wrapper
@note
def test():
'''test function'''
print('I am test')
print(help(test))
# 输出:
# test()
# test function
参考资料:
Python 面向对象进阶(二)的更多相关文章
- Python面向对象进阶(二)
Python面向对象进阶2.html :first-child{margin-top:0!important}img.plugin{box-shadow:0 1px 3px rgba(0,0,0,.1 ...
- Python面向对象进阶和socket网络编程-day08
写在前面 上课第八天,打卡: 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __i ...
- Python面向对象进阶和socket网络编程
写在前面 为什么坚持?想一想当初: 一.面向对象进阶 - 1.反射补充 - 通过字符串去操作一个对象的属性,称之为反射: - 示例1: class Chinese: def __init__(self ...
- Python开发【第七篇】:面向对象 和 python面向对象进阶篇(下)
Python开发[第七篇]:面向对象 详见:<Python之路[第五篇]:面向对象及相关> python 面向对象(进阶篇) 上一篇<Python 面向对象(初级篇)> ...
- python面向对象进阶(八)
上一篇<Python 面向对象初级(七)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使 ...
- python 面向对象进阶之内置方法
一 isinstance(obj,cls)和issubclass(sub,super) 1.1,isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(obj ...
- Python 面向对象 (进阶篇)
<Python 面向对象(初级篇)>文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可 ...
- python面向对象进阶
前言 上节大话python面向对象对面向对象有了一些了解,这次就不用大话风格了 (ps:真心不好扯啊) isinstance与issubclass isinstance(obj,cls)检查是否obj ...
- Python基础之面向对象进阶二
一.__getattribute__ 我们一看见getattribute,就想起来前面学的getattr,好了,我们先回顾一下getattr的用法吧! class foo: def __init__( ...
随机推荐
- am335x -- kio 控制接口
//example #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include < ...
- Android——UI事件的处理机制(基于监听器)
1.普通内部类(常用) xml <Button android:hint="reset" android:layout_columnWeight="1" ...
- PHP——注册页面,审核页面,登录页面:加Session和Cookie
实现效果: 用户注册信息,管理员核对信息审核通过后,可实现注册的用户名和密码的成功登陆,利用session和cookie获取用户信息并且不能跳过登录页面直接进入主页面 1.Session存储在服务器可 ...
- Scala中List(Map1,Map2,Map3 ....) 转成一个Map
这个问题研究好久...头大,不记得有fold用法了. fold函数:折叠,提供一个输入参数作为初始值,然后大括号中应用自定义fun函数并返回值. list.fold(Map()){(x,y)=> ...
- Farey Sequence(欧拉函数)
题意:给出式子F F中分子分母互质,且分子小于分母 例: F2 = {1/2} F3 = {1/3, 1/2, 2/3} F4 = {1/4, 1/3, 1/2, 2/3, 3/4} F5 = {1/ ...
- Golang 中操作 Mongo Update 的方法
Golang 和 MongoDB 中的 ISODate 时间交互问题 2018年02月27日 11:28:43 独一无二的小个性 阅读数:357 标签: GolangMongoDB时间交互时间转换 更 ...
- 本机添加多个git仓库账号
我们可能会需要在一台电脑上以不同的github账户去使用git,这时就需要去解决如何管理本机上的多个ssh key的问题了. 生成新ssh key 如果我们电脑上已经存在了一个ssh key,那么我们 ...
- APP纯黑盒测试—某些可以试试的操作
一.多次快速点击一处功能入口: 该测试方法可以在某些应用中打开俩次目标界面,举一些具体一点的例子: 1.比如现在很多APP需要登陆,如果打开了俩次登录页面,就容易造成登录成功后应用跳转界面又是登录界面 ...
- cssText方式写入css
<div class="a" id="a">hello world</div> <script> //通过JS来覆写对象的样 ...
- C++继承具体解释之二——派生类成员函数具体解释(函数隐藏、构造函数与兼容覆盖规则)
在这一篇文章開始之前.我先解决一个问题. 在上一篇C++继承详解之中的一个--初探继承中,我提到了在派生类中能够定义一个与基类成员函数同名的函数,这样派生类中的函数就会覆盖掉基类的成员函数. 在谭浩强 ...