class inTuple(tuple):
def __new__(cls,iterable):
g=(x for x in iterable if isinstance(x,int) and x>0)
return super(inTuple,cls).__new__(cls,g)
def __init(self,iterable):
#before
print (self)
super(InTuple,self)._init__(iterable)
#如何为创建大量实例节省内存
#定义类的__slots__属性,它是用来声明实例属性名字的列表
import sys
sys.getsizeof(p2,dict)
class player(object):
__slots__ = ['uid','name','stat','level']
def __init__(self,uid,name,status=0,level=1):
self.uid=uid
self.name=name
self.stat=status
self.level=level
#如何让对象支持上下下文管理
with open('demo.txt','w') as f:
f.write('abcdef')
f.writelines(['xyz\n','123\n'])
from telnetlib import Telnet
from sys import stdin,stdout
from collection import deque
class TelnetClient(object):
def __init__(self,addr,port=33):
self.addr=addr
self.port=port
self.tn=None
def start(self):
# self.tn=Telnet(self.addr,self.port)
# self.history=deque()
#user
t=self.tn.read_until('login:')
stdout.write(t)
user=stdin.readline()
self.tn.write(user)
#password
t=self.tn.read_until('Password:')
if t.startswith(user[:-1]):t=t[len(user)+1:]
stdout.write(t)
self.tn.write(stdin.readline())
t=self.tn.read_until('$')
stdout.write(t)
while true:
uinput=stdin.readline()
if not uinput:
break
self.history.append(uinput)
self.tn.write(uinput)
t=self.tn.read_until('$')
stdout.write(t[len(uinput)+1:])
def cleanup(self):
# self.tn.close()
# self.tn=None
# with open(self.addr + '_history.txt','w') as f:
# f.writelines(self.history)
client=TelnetClient('127.0.0.1')
client.start()
#实现上下文管理协议,需定义实例的__enter__,__exit__方法,它们分别在with开始和结束时调用
def __enter__(self):
self.tn = Telnet(self.addr, self.port)
self.history = deque()
return self
def __exit__(self,exc_type,exc_val,exc_tb):
self.tn.close()
self.tn = None
with open(self.addr + '_history.txt', 'w') as f:
f.writelines(self.history)
with TelnetClient('127.0.0.1') as client:
client.start()
#在面向对象编程中,我们把方法函数看作对象的接口,直接访问对象的属性可能是不安全的的,但是使用调用方法在形式上不如访问属性简洁
circle.getradius()
circle.getradius(5.0)
circle.getradius
#使用property函数为类创建可管理属性,fget/fset/fdel对应相应属性访问。
class Rectangle:
def __init__(self,w,h):
self.w=w
self.h=h
def area(self):
return self.w*self.h
rect1=Rectangle(5,3)
#如何让类支持比较运算符
#比较运算符重载,需要实现一下的方法:
#__it__,__le__,__gt__,__ge__,__eq__,__ne__使用标准库下的functools下的类的装饰器total_orddering可以简化此过程
def __lt__(self,obj):
return self.area()<obj.area()
print (r2<r1)#r1._lt__(r2)
from functools import total_ordering
@total_ordering
class Rectangle:
def __init__(self, w, h):
self.w = w
self.h = h
def area(self):
return self.w * self.h
rect1=Rectangle(5,3)
def __lt__(self, obj):
return self.area() < obj.area()
print(r2 < r1) # r1._lt__(r2)
#如何使用描述符对实例属性做类型检查
class Descriptor(object):
def __get__(self, instance, cls):
#return instance.dict_[xxx]
def __set__(self, instance, value):
#instance.dict_[xxx]=value
def __delete__(self, instance):
#del instance._dict_[xxx]
class A(object):
x=Descriptor
a=A()
a.x
A.x
class Attr(object):
def __init__(self,name,type_):
self.name=name
self.type=type_
def __get__(self, instance, cls):
return instance.dict_[self.name]
def __set__(self, instance, value):
if not isinstance(value,self.type_):
raise TypeError("expected as %s" % self.type_)
instance.dict_[self.name]=value
def __delete__(self, instance):
del instance._dict_[self.name]
class Person(object):
name=Attr('name',str)
age = Attr('age', int)
height = Attr('height', float)
x = Descriptor
p=Person()
p.name='bob'
print (p.name)
#如何在环状数据结构中管理内存
#在python中,垃圾回收器通过引用计数来回收垃圾对象,但某些环状数据结构树图,存在对象间的循环引用,比如树的父节点引用子节点,子节点也同时引用父节点,此时同时del掉父节点,两个对象不能被立即回收,如何解决此类问题的内存管理问题
class A(object):
def __del__(self):
print ('in.A.__del__')
a=A()
import sys
sys.getrefcount(a)-1
#解决办法;使用标准库weakref,他可以创建一种能访问对象但不增加引用计数的对象
class Data(object):
def __init__(self,value,owner):
self.owner=owner
self.value=value
def __str__(self):
return "%s 's data,value is %s" %(self.owner,self.value)
def __del__(self):
print('in Data.del_')
class Node(object):
def __init__(self,value):
self.data =Data(value,self)
def __del__(self):
print('in Node.del_')
node=Node(100)
raw_input('wait......')
del node
import weakref
a_wref=weakref.ref(a)
a2 =a_wref()
a is a2
#如何通过实例方法名字的字符串调用方法
# 方法一:使用内置函数getattr,通过名字在实例上获取方法对象,然后调用
# 方法二:使用标准库operator下的methodcaller函数调用
def getArea(shape):
for name in('area','getArea','get_area'):
f =getattr(shape,name,None)
if f:
return f()
from operator import methodcaller
s ='abc123abc456'
s.find('abc',4)
methodcaller('find','abc',4)(s)
#如何使用多线程
import csv
from xml.etree.ElementTree import Element,ElementTree
import requests
from StringIO import StringIO
from xml_pretty import pretty
def download(url):
response =requests.get(url,timeout=3)
if response.ok:
return StringIO(response.content)
def csvToXml(scsv,fxml):
reader =csv.reader(scsv)
headers=reader.next()
headers = map(lambda h:h.replace(' ',''),headers)
root = Element('Data')
for row in reader:
eRow =Element('Row')
root.append(eRow)
for tag,text in zip(headers,row):
e=Element(tag)
e.text=text
eRow.append(e)
pretty(root)
et=ElementTree(root)
et.write(fxml)
if __name__ == '__main__':
url = ' httplll'
rf =download(url)
if rf:
with open('dd.xml','wb') as wf:
csvToXml(rf,wf)
for sid in xrange(1,11):
print('download...(%d)' % sid)
url='htt[;'
url %=str(sid).rjust(6.'0')
rf = download(url)
if rf is None:continue
print('covert to XML...(%d)' % sid)
#使用标准库threading.thread创建线程,在每一个线程中下载并转换一只股票数据
def handle(sid):
print('download...(%d)' % sid)
url = 'htt[;'
url %= str(sid).rjust(6.
'0')
rf = download(url)
if rf is None: continue
print('covert to XML...(%d)' % sid)
from Threading import Thread
t=Thread(target=handle,args=(1,))
t.star()
class MyThread(Thread):
def __init__(self,sid):
Thread.__init__(self)
self.sid=sid
def run(self):
handle(self.sid)
threads = []
for i in xrange(1,11):
t=MyThread(1)
threads.append(t)
t.start()
for t in threads:
t.join()