封装的意义:
第一层意义:创建类和对象时,分别创建两者的名称空间。只能通过类名加“.”或者obj.的方式访问里面的名字;
第二层意义:类中把某些属性和方法隐藏起来,或者定义为私有,只在类的内部使用,在类的外部无法访问,或者留下少量的接口(函数)供外部访问;
接着昨天的类的定义的火车站信息爬虫代码进行改进,实现封装,代码如下:
import requests
class Station():
def __init__ (self,code,cn,qp,jp):
#加入两个下划线可将其设为隐藏属性
self.__code=code
self.__cn=cn
self.__qp=qp
self.__jp=jp
def printinfo(self):
print(self.__code,self.__cn,self.__qp,self.__jp)
def test(self):
#self代表类的实例,表示当前对象的地址 self.__class__ 则指向类
print(self)
print(self.__class__)
def getcode(self,s):
if s in [self.__cn,self.__qp,self.__jp]:
return self.__code
def __str__(self):
return "\t".join([self.__code, self.__cn, self.__qp, self.__jp])
def getstations(address):
while 1:
find_address=input("%s站:"%address)
address_list=list(filter(lambda i:i.getcode(find_address),stations))
if len(address_list)==1:
return address_list[0]
elif len(address_list)>1:
for i in range(len(address_list)):
print(i+1,address_list[i])
select_address = int(input("输入选择的序号:"))
return address_list[select_address-1]
else:
print("查询地址不存在,重新输入!")
url="https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9077"
html_txt=requests.get(url).text
#split后可以直接存入列表
infos=html_txt[:-2].split('@')[1:]
#print(infos)
stations=[]
for info in infos:
station_list = info.split('|')
stations.append(Station(station_list[2],station_list[1],station_list[3],station_list[4]))
for i in stations[:10]:
i.printinfo()
i.test()
cf_station=getstations("出发")
dd_station=getstations("到达")
print(cf_station,dd_station)
在这里,我们对类中的属性前面加入两个下划线将其设为隐藏属性;
此时,便不可以使用obj.的属性进行访问;
同时,在写这段代码时学习到了列表生成器的使用,具体使用方法的代码如下:
address_list=list(filter(lambda i:i.getcode(find_address),stations))
实现的效果如下图:
enen~~ 就酱紫!