第16次全天课笔记 20181111 面向对象2
全天课笔记-20181111
核心编程 面向对象 5遍 200页
用类实现一个图书馆,实现借书,入库,还书,查书,等功能,要求数据可以保存到文件中,退出后下次可以找回数据
#第一题,用类实现一个图书馆,实现借书,
#入库,还书,查书,等功能,
#要求数据可以保存到文件中,退出后下次可以找回数据
#今天就一个题,稍微复杂点
import traceback
import pickle
import os
import os.path
class Book(object):
def __init__(self,name,author,tag,price):
self.__name = name
self.__author = author
self.__tag = tag
self.__price = price
def get_book_name(self):
return self.__name
def set_book_name(self,new_name):
self.__name = new_name
def book_info(self):
print(self.name,self.author,self.tag,self.price)
class GRLibrary(object):
'''吴老师创建的创建的光荣之路图书馆!'''
def __init__(self,name,location):
self.name = name
self.location = location
self.book_list=[]
def get_library_info(self):
info = "名字:%s \n地点:%s" %(self.name,self.location)
return info
def add(self,book):
self.book_list.append(book)
print("%s图书入库成功" %book.get_book_name())
def list(self):
for book in self.book_list:
print(book.get_book_name())
def list_info():
print("""
图书馆可以输入如下命令进行操作:
create:创建图书馆
use:使用某个图书馆
add:增加图书
borrow:借阅图书
lend:还书
list:查看库中的图书列表
search:查看库中是否存在某本书
exit:退出
""")
library = None
def create():
global library
library_name= input("请输入图书馆的名字:").strip()
location = input("请输入图书馆的地址:").strip()
library = GRLibrary(library_name,location)
def add():
book_name=input("请输入书名:").strip()
author_name=input("请输入作者名:").strip()
tag= input("请输入书的分类:").strip()
price = input("请输入书的价格:").strip()
book= Book(book_name,author_name,tag,price)
if library is not None:
library.add(book)
print("%s 图书入库成功" %book_name)
else:
print("图书馆还未创建,请输入create进行创建!")
def list_book():
if library is not None:
library.list()
library_data_file_path =""
def use():
global library
global data_file_path
data_file_path = input("请输入图书馆数据文件的位置:").strip()
if os.path.exists(data_file_path):
try:
fp= open(data_file_path,"rb")
library=pickle.load(fp)
library_data_file_path = data_file_path
except:
print("图书馆的数据文件没有合法的数据!")
command ={"create":"create","add":"add","list":"list_book","use":"use"}
if __name__ == "__main__":
print(list_info())
while 1:
try:
user_command = input("请输入操作命令:").lower().strip()
if user_command=="exit":
if library_data_file_path == "":
library_data_file_path = input("请输入保存图书馆数据的数据文件路径:")
fp= open(library_data_file_path,"wb")
if library is not None:
pickle.dump(library,fp)
fp.close()
break
eval(command[user_command]+"()")
except:
traceback.print_exc()
if user_command not in command:
print("您输入命令不存在!")
else:
print("您输入的命令有误,请按照命令列表输入:")
print(list_info())
continue
情商:
1 早饭钱
2 技巧:某个o
1 他会走在前面帮你开门
2 主动盛汤
3 换位思考
卡耐基:
你领导的生日
唐骏:
看待一个人,会保持一颗真诚的心。
150人。重点分配,你觉得对你非常有帮助的即可。
礼尚往来
拍马屁,暗爽。
夸人一定要真诚。
支持某个人。
换位思考:对方需要什么?让开心一点。
观察:销售、商务人员、保险。
#coding=utf-8
import os
class Person(object):
def __init__(self,name):
self.Name = name
def getName(self):
print ('fetch...')
return self.Name
def setName(self, name):
print ('change...')
self.Name = name
def delName(self):
print ('remove...')
del self.Name
name = property(getName,setName,delName,'name property docs')
# name=property(getName,setName)
bob = Person('Bob Smith')
print (bob.name)
bob.name = 'Robert Smith'
print (bob.name)
del bob.name
#coding=utf-8
class Student():
def __init__(self, name, age, score):
self.name = name
self.age = age
self.__score = score
def set_score(self, score):
if not isinstance(score, int):
raise ValueError("score must be an interger!")
if score < 0 or score > 100 :
raise ValueError("score must be between 0 - 100!")
self.__score = score
def get_score(self):
return self.__score
s = Student('tom', 19, 90)
print ("score is ", s.get_score())
try :
s.set_score("a")
except Exception as e:
print ("score error!")
#coding=utf-8
from datetime import datetime
class Student(object):
@property
def birth(self):
return self._birth
@birth.setter
def birth(self, value):
self._birth = datetime.strptime(value, '%Y-%m-%d')
print (self._birth)
@property
def age(self):
currentTime = datetime.now()
currentDate = currentTime.strftime('%Y-%m-%d')
# print (currentDate)
# print (self._birth)
timedelta = datetime.strptime(currentDate, '%Y-%m-%d') - self._birth
# print (timedelta)
return timedelta.days / 365
if __name__ == '__main__' :
s = Student()
s.birth = '1992-08-18'
print ("现在年龄:", s.age)
s.age=1000
class A
speak(){"A"}
class B extends A
speak(){"B"}
a=new A()
b=new B()
say(A x)
x.speak()
say(a)-->"A"
say(b)-->"B"
多态:方法不变,依据参数的值,方法可以实现不同的输出
多态:某个函数依据参数的实例类型(通常是基类实例
或者子类实例),可以实现不同的输出
class F1:
pass
class S1(F1):
def show(self):
print ('S1.show')
class S2(F1):
def show(self):
print ('S2.show')
def Func(obj):
"""Func函数需要接收一个F1类型或者F1子类的类型"""
obj.show()
s1_obj = S1()
Func(s1_obj) # 在Func函数中传入S1类的对象 #s1_obj,执行 S1 的show方法,结果:#S1.show
s2_obj = S2()
Func(s2_obj) # 在Func函数中传入Ss类的对象 #ss_obj,执行 Ss 的show方法,结果:#S2.show
class calculator:
def count(self,args):
return 1
calc=calculator()
#自定义类型
from random import choice
#obj是随机返回的类型不确定
obj=choice(['hello,world',[1,2,3],calc])
print (obj)
print (type(obj))
print (obj.count('a')) #方法多态
#coding=utf-8
def add(x,y):
return x+y
print (add(1,2)) #输出3)
print (add("hello,","world") )#输出hello,world
print (add(1,"abc")) #将抛出异常 TypeError,不同类型不能相加'
重写父类的成员方法
#coding=utf-8
class Parent(object): # 定义父类
def myMethod(self):
print ('call Parent')
def printName(self):
print ("my name is LiLy")
class Child(Parent): # 定义子类
def myMethod(self): # 子类重写父类myMethod方法
Parent.myMethod(self)
print ('call Child')
c = Child() # 子类实例
c.myMethod() # 子类调用重写方法
c.printName() # 子类调用从父类继承过来但未被重写的方法
运算符重写
class Vector(object) :
def __init__(self, a, b) :
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other) :
return Vector(self.a + other.a, self.b + other.b)
x = Vector(3,7)
y = Vector(1, -10)
print (x + y)
print (str(x))
>>> class P:
... def __del__(self):
... print("bye!")
...
>>> p=P()
>>> del p
bye!
文档字符串
>>> class P:
... """P class"""
... pass
...
>>> p=P()
>>> p.__doc__
'P class'
p.__module__ 模块
p.__class__ 类名
>>> p.__module__
'__main__'
>>> p.__class__
<class '__main__.P'>
>>> class P:
... def __repr__(self):
... print("repr is invoked!")
... return "repr method!"
... def __str__(self):
... print("str method is invoked!")
... return "str method!"
...
>>> p = P()
>>> p #默认调用repr方法
repr is invoked!
repr method!:
>>> print(p) #调用str方法
str method is invoked!
str method!
>>>
Call 方法:
>>> class P:
... def __call__(self):
... print ("call me now!")
...
>>> p =P()
>>> p
<__main__.P object at 0x0000000002596CC0>
>>> p()
call me now!
>>> class P:
... pass
...
>>> p=P()
>>> p()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'P' object is not callable
>>> class P:
... def __call__(self,value):
... print(value)
...
>>> p=P()
>>> p(100)
100
>>> class P:
... number =100
... def __init__(self,value):
... self.value = value
... def print_sth(self):
... pass
...
>>> p=P(1)
>>> p.__dict__
{'value': 1}
>>> P.__dict__
mappingproxy({'__module__': '__main__', 'number': 100, '__init__': <function P._
_init__ at 0x00000000024C8BF8>, 'print_sth': <function P.print_sth at 0x00000000
024C8C80>, '__dict__': <attribute '__dict__' of 'P' objects>, '__weakref__': <at
tribute '__weakref__' of 'P' objects>, '__doc__': None})
>>>
__getitem__ 、__setitem__ 、__delitem__
# -*- coding:utf-8 -*-
class Foo(object):
def __getitem__(self, key):
print ('__getitem__',key)
def __setitem__(self, key, value):
print ('__setitem__',key,value)
def __delitem__(self, key):
print ('__delitem__',key)
obj = Foo()
result = obj['k1'] # 自动触发执行 __getitem__
obj['k2'] = 'wupeiqi' # 自动触发执行 __setitem__
del obj['k1'] # 自动触发执行 __delitem__
实现类似字典的功能:obj['k1']如果存在,读出来值
不存在返回None
obj['k2'] = 'wupeiqi' 可以赋值成功并且通过obj['k2']来读取值
删除obj['k2'] 的时候,把k2的value和key都删除
提示:类有个实例变量是个字典来实现上面的功能
# -*- coding:utf-8 -*-
class Foo(object):
d = {}
def __getitem__(self, key):
if key in self.d:
return self.d[key]
else:
return None
def __setitem__(self, key, value):
self.d[key]=value
def __delitem__(self, key):
if key in self.d:
del self.d[key]
print("del %s" %key)
obj = Foo()
result = obj['k1'] # 自动触发执行 __getitem__
print(result)
obj['k2'] = 'wupeiqi' # 自动触发执行 __setitem__
print(obj['k2'])
del obj['k2'] # 自动触发执行 __delitem__
class P:
number =100
def __init__(self):
print (P.number)#通过类名调用类变量
print (self.number)#通过实例调用类变量
self.number=30 #生成了新的实例变量,覆盖了类变量Number
print (self.number)#通过实例变量把类变量覆盖了
@classmethod #类方法,必须有cls的参数,不能包含实例变量
def func(cls,value):
print(P.number)
print(value) #局部变量
@staticmethod #静态方法,不能包含实例变量
def func1(value):
print(P.number)
print(value) #局部变量
def print_str(self,content): #实例方法,可以包含实例变量和类变量
print(content) #局部变量
print(self.number) #访问实例变量
print(P.number) #访问类变量
#类是模板P
#实例是通过模板生成的产品p
#P.func(50)#调用类方法
p=P() #实例化
p.func(50) #调用类方法
p.print_str("gloryroad")#通过实例调用实例方法
#P.print_str("gloryroad")#通过类名调用实例方法,会出错
P.func1("gr") #通过类名调用静态方法
p.func1("gr") #通过实例调用静态方法
class Foo:
def __init__(self,name,age):
self.name=name
self.age=age
self.li=[1,2,3,4,5,6,7]
self.li2=[5,6,7,8,8]
def __getitem__(self, item):
# 匹配:对象[item]这种形式
print(item) #slice(2,4,None)==[2:4]
if isinstance(item,slice):
# 如果是slice对象,返回切片后的结果
print( self.li2[item] ) # 返回切片结果
elif isinstance(item,int):
# 如果是整形,说明是索引
return self.li[item]
def __setitem__(self, key, value):
# 匹配:对象[key]=value这种形式
print(key,value)
self.li[key] = value
def __delitem__(self, key):
# 匹配:del 对象[key]这种形式
print(key)
del self.li[key]
li=Foo("alex",18)
print(li[3:5]) #调用__getitem__方法
li[0]=100 #调用__setitem__方法
print(li[0]) #调用__getitem__方法
del li[0] #调用__delitem__方法
print(li[0]) #调用__getitem__方法
__iter__
class Foo(object):
def __init__(self, sq):
self.sq = sq
def __iter__(self):
return iter(self.sq)
obj = Foo([11,22,33,44])
for i in obj:
print (i)
__slot__
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
s = Student() # 创建新的实例
s.name = 'Michael' # 绑定属性'name'
s.age = 25 # 绑定属性'age'
s.score = 99 # 绑定属性'score
真正的实例对象是new产生的
class A(object):
def __init__(self):
print ("init")
def __new__(cls,*args, **kwargs):
print ("new %s"%cls)
return object.__new__(cls, *args, **kwargs)
A()