zoukankan      html  css  js  c++  java
  • 练习41:学着去说面向对象

    一 词汇训练

    • 类(class):告诉python创建一个新类型的东西。(Tell python to make a new type of thing).
    • 对象(object):两种含义:最基本类型的东西,任何实例。(the most basic type of thing,and any instance of something)。
    • 实例(instance):当你告诉python创建一个类的时候你所得到的东西。(What you get when you tell pythong to create a class).
    • def:你如何在类里面定义一个函数。(How you define a function inside a class)。
    • self:在一个类的函数里面,self是被访问的实例/对象的一个变量。(inside the functions in a class,self is a variable for the instance/object being accessed)。
    • 继承(inheritance):关于一个类能从另一个类那里继承它的特征的概念,很像你和你的父母。(The concept that one class can inhert traits from other class,much like you and your parents)。
    • 组合(composition):关于一个类可以由其它一些类构成的概念,很像一辆车包含几个轮子。(The concept that a class can be composed of other classes as parts,much like how a car has wheels)。
    • 属性(attribute):类所拥有的从组合那里得到的特性,通常是变量。(A property classes have that are from composition and are usually variables)。
    • is-a:一种用来表达某物继承自一种东西的表述,就像“三文鱼是一种鱼”。(A phrase to say that something are from inherits from another,as in a "salmon" is a "fish")
    • has-a:一种用来表达某物是由一些东西组成或具有某种特性的表述,就像“三文鱼有一个嘴巴。”(A phrase to say that something is composed of other things or has a trait,as in "a salmon has-a mouth.")

    二 短语训练

    • class X(Y) :创建一个名为 X 并继承自 Y 的类。(“Make a class named X that is-a Y.”)
    • class X(object): def __init__(self, J):类 X 有一个带有 self 和 J 参数的 __init__ 函数。(“class X has-a __init__ that takes self and J parameters.”)
    • class X(object): def M(self, J) :类 X 有一个带有 self 和 J 参数的 M 函数。(“class X has-a function named M that takes self and J parameters.”)
    • foo = X() :设 foo 为类 X 的一个实例。(“Set foo to an instance of class X.”)
    • foo.M(J)  从 foo 那里获取 M 函数,并用 self 和 J 参数来调用它。(“From foo, get the M function, and call it with parameters self, J.”)
    • foo.K = Q  从 foo 那里获取 K 属性,并设它为 Q。(“From foo, get the K attribute, and set it to Q.”)

    三 代码

    1 urllib标准库

    • 网络爬虫简介:
      • 定义:按照一定规则,自动抓取万维网信息的程序或脚本。
      • 两大特征:
        • 能按程序员要求下载数据或者内容
        • 能自动在网络上流窜(从一个网页跳转到另一个网页)
      • 两大步骤:
        • 下载网页
        • 提取正确的信息
        • 根据一定规则自动跳转其它撤销页面上执行以上两步操作
      • 爬虫分类:
        • 通用爬虫(常见的搜索引擎)
        • 专用爬虫(聚集爬虫)
      • python常用的网络包:
        • Python3:urllib、requests
    • urllib库:
      • 是什么:urllib是python内置的处理HTTP请求的库
      • 有什么:主要包含以下四个模块
        • urllib.request 请求模块:它是最基本的 HTTP 请求模块,我们可以用它来模拟发送一请求,就像在浏览器里输入网址然后敲击回车一样,只需要给库方法传入 URL 还有额外的参数,就可以模拟实现这个过程了。
        • urllib.error 异常处理模块:如果出现请求错误,我们可以捕获这些异常,然后进行重试或其他操作保证程序不会意外终止。
        • urllib.parse url解析模块: parse 模块是一个工具模块,提供了许多 URL 处理方法,比如拆分、解析、合并等等的方法。
        • urllib.robotparser robots.txt解析模块:主要是用来识别网站的 robots.txt 文件,然后判断哪些网站可以爬,哪些网站不可以爬的,其实用的比较少。
    • urllib.request.urlopen函数:
      • 功能:用于实现对目标url的访问。
      • 函数原型:urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
      • 参数介绍:一般常用的有三个——url,data,timeout
        •  url 参数:目标资源在网路中的位置。可以是一个表示URL的字符串(如:https://www.boxuegu.com);也可以是一个urllib.request对象。
        • data参数:data用来指明发往服务器请求中的额外的参数信息(如:在线翻译,在线答题等提交的内容),HTTP是python中实现的众多网络通信http、https、ftp等协议中,唯一一个 使用data 参数的,也就是说只有打开的是http网址的时候,自定义data参数才会有作用。
          • data必须是一个字节数据对象(Python的bytes object)
          • data必须符合标准the standard application/x-www-form-urlencoded format,怎么得到这种标准结构的data呢?使用urllib.parse.urlencode()将自定义的data转换成标准格式,而这个函数所能接收的参数类型是pyhon中的mapping object(键/值对,如dict) or a sequence of two-element tuples(元素是tuple的列表)。
          • data也可以是一个可迭代的对象,这种情况下就需要配置response对象中的Conten-length,指明data的大小。
          • data默认是None,此时以GET方式发送请求;当用户给出data参数的时候,改为POST方式发送请求。
        • timeout参数:设置超时时间,单位是秒。
          • 如果请求超过这个时间还没有得到响应,就会抛出异常。如果没有设定的话,就会使用全局的默认时间。支持HTTP,HTTPS,FTP!
          • 我们可以设置超时时间来控制网页爬取时间超过规定时间就跳出,使用try except语句是实现。
        • context参数:实现SSL加密传输。(基本上很少用)
        • cafile、capath参数:是指定 CA 证书和它的路径,这个在请求 HTTPS 链接时会有用。(基本很少用)
        • cadefault 参数现在已经弃用了,默认为 False。
      • urlopen返回对象提供方法:
        • read() , readline() ,readlines() , fileno() , close() :对HTTPResponse类型数据进行操作
        • info():返回HTTPMessage对象,表示远程服务器返回的头信息
        • getcode():返回Http状态码。如果是http请求,200请求成功完成;404网址未找到
        • geturl():返回请求的url
      • 版本区别:python2和python3在导入urlrequest的方式是不一样的。
        • python2中:import urllib2
        • python3里面把urllib分开了,分成了urlrequest和urlerror,在这里我们只需导入urlrequest即可。from urllib.request import urlopen
    • Request类
      • 功能:urlopen()可以实现简单的请求,但是它无法添加一些header信息,也就不能构建一个完整的请求。所以我们可以用Request类来构建一个完整的请求。
      • 函数原型:class urlib.request.Request(url,data=None,headers={},origin_req_host=None,unverifiable=False,method=None)
      • 参数介绍:
        • url:请求的url ,必传参数。
        • data: 类型是bytes类型,如果是字典,使用urllib.parse中的urlencode()编码!
        • headers:参数是一个字典,表示请求的请求标识和载体!可以在构造 Request 时通过 headers 参数直接构造,也可以通过调用Request实例的add_header()方法来添加。 Request Headers 最常用的用法就是通过修改 User-Agent 来伪装浏览器,默认的 User-Agent 是 Python-urllib,我们可以通过修改它来伪装浏览器。
        • origin_host:表示请求的host名称或者IP地址。
        • unverifiable:参数表示这个请求是否是无法验证的,默认是False.意思就是说用户没有足够权限来选择接收这个请求的结果。例如我们请求一个 HTML 文档中的图片,但是我们没有自动抓取图像的权限,这时 unverifiable 的值就是 True。
        • method:是一个字符串,它用来指示请求使用的方法,比如GET,POST,PUT等等。
    • 异常处理:
      • 功能:urllib 的error模块定义了由request模块产生的异常。如果出现了问题,request模块就会抛出error模块中定义的异常!
      • 两个常见的异常:URLError,HTTPError,HTTPError是URLError的子类
        • URLError里只有一个属性:reason,即抓异常的时候只能打印错误信息
        • HTTPError里有三个属性:code,reason,headers,即抓异常的时候可以获得code,reson,headers三个信息
          • code,返回 HTTP Status Code,即状态码,比如 404 网页不存在,500 服务器内部错误等等。
          • reason,同父类一样,返回错误的原因。
          • headers,返回 Request Headers。
        • 因为 URLError 是 HTTPError 的父类,所以我们可以先选择捕获子类的错误,再去捕获父类的错误
    • Url解析:
      • urlparse()
        • 功能:对你传入的url地址按特定的协议类型进行拆分
        • 原型:urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
          • urlstring:url地址参数
          • scheme:指定协议类型,如果url里面已经带了协议,再通过scheme指定的协议就不会生效
      • urlunpars():用于拼接
      • urljoin():也用做拼接
      • urlencode():可以将字典转换为url参数
    • 参考内容:

    2 random模块

    • 功能:用于生成随机数
    • 常见方法:
      • random.random():生成一个随机的浮点数,范围是在0.0~1.0之间
      • random.uniform(a,b) :用于生成一个指定范围内的随机符点数,两个参数其中一个是上限,一个是下限。如果a > b,则生成的随机数n: b <= n <= a。如果 a <b, 则 a <= n <= b。
      • random.randint(a, b):用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b
      • random.randrange([start], stop[, step]):从指定范围内,按指定基数递增的集合中 获取一个随机数。
      • random.choice(sequence):可以从任何序列,比如list列表中,选取一个随机的元素返回,可以用于字符串、列表、元组等。
      • random.shuffle(x[, random]):原地指定seq序列,用于将一个列表中的元素打乱,即将列表内的元素随机排列。
      • random.sample(sequence, k):从指定序列中随机获取指定长度的片断并随机排列。注意:sample函数不会修改原有序列。

    2 代码

    它所做的事情就是用一个叫做 urllib 的图书馆来下载一列单词。
     1 import random                                      # 导入random模块
     2 from urllib.request import urlopen                 # 导入urllib库中的urlopen方法
     3 import sys                                         # 导入sys模块
     4 
     5 WORD_URL = "http://learncodethehardway.org/words.txt"       # 保存要访问的网页地址Url
     6 WORDS = []
     7 
     8 PHRASES = {
     9     "class %%%(%%%):":
    10         "Make a class named %%% that is-a %%%.",
    11     "class %%%(object):
    	def __init__(self,***)":
    12         "class %%% has-a __init__ that takes self and *** params.",
    13     "class %%%(object):
    	def ***(self,@@@)":
    14         "class %%% has-a function *** that takes self and @@@ params.",
    15     "*** = %%%()":
    16             "Set *** to an instance of class %%%.",
    17     "***.***(@@@)":
    18             "From *** get the *** function,call it with params self @@@.",
    19     "***.*** = '***'":
    20             "From *** get the *** attribute and set it to '***'."
    21 }                                                          # 存储类、函数、方法的定义或者调用格式
    22 
    23 # do they want to drill phrases first
    24 if len(sys.argv) == 2 and sys.argv[1] == "english":        # 如果命令行参数有两个,且第二个参数是english,即在执行过程中命令行参数必须有两个,第一个是脚本文件名,第二个是english
    25     PHRASE_FIRST = True                                    # PHRASE_FIRST值为True
    26 else:
    27     PHRASE_FIRST = False                                   # 否则PHRASE_FIRST值为False
    28 
    29 # load up the words from the website
    30 for word in urlopen(WORD_URL).readlines():                 # 打开WORD_URL对应的网页地址,并返回有每行内容组成的列表(会保存在硬盘中),再通过for循环遍历得到的列表
    31     WORDS.append(str(word.strip(),encoding="utf-8"))       # 去除每行的头尾空白后,将其转换成字符串,并采用utf-8格式编码,将编码后的内容添加到列表WORDS中
    32 
    33 def convert(snippet,phrase):                               # 将字典的键和值中的特殊符号和从WORDS_URL中读到的内容进行替换
    34     class_names = [w.capitalize() for w in                 # 利用for循环遍历的到的随机列表,并将列表元素字符串中的第一个字母变大写,其它字母变小写
    35                                                            # snippet.count()表示统计PHARSES字典的键里面某个字符串出现的次数,即为伪装一个类名或其它内容需要的单词的个数
    36     random.sample(WORDS,snippet.count("%%%"))]             # 通过分片的方式从列表WORDS中得到长度为snippet.count("%%%")的列表,然后将分片得到的列表内部元素随机排列
    37     other_names = random.sample(WORDS,snippet.count("***"))# 通过分片的方式从列表WORDS中得到长度为snippet.count("***")的列表,然后将分片得到的列表内部元素随机排列
    38     results = []
    39     param_names = []
    40     
    41     for i in range(0,snippet.count("@@@")):
    42         param_count = random.randint(1,3)                  # 利用random.randint()函数产生一个1、2、3中的随机整数,控制分片后列表的长度
    43         param_names.append(','.join(                       # 用","将分片后得到的列表的内容连接成字符串
    44             random.sample(WORDS,param_count)))             # 利用param_count将WORDS列表分片,然后将分片得到的列表内部元素随机排列
    45     
    46     for sentence in snippet,phrase:                        # 用sentence遍历PHRASES字典的键和值
    47         result = sentence[:]                               # 利用切片操作完成对sentence列表的复制
    48         
    49         # fake class names                                 # 伪装类名称
    50         for word in class_names:
    51             result = result.replace("%%%",word,1)          # 将result中的字符串"%%%"用class_names中得到的word代替,替换不超过一次
    52         
    53         # fake other names                                 # 伪装函数或方法等其它内容的名称
    54         for word in other_names:
    55             result = result.replace("***",word,1)          # 将result中的字符串"***"用other_names中得到的word代替,替换不超过一次
    56         
    57         # fake parameter lists                             # 伪装参数列表
    58         for word in param_names:
    59             result = result.replace("@@@",word,1)          # 将result中的字符串"@@@"用param_names中得到的word代替,替换不超过一次
    60         
    61         results.append(result)                             # 将result添加到列表results当中,并返回results列表的值
    62     return results
    63 
    64 # keep going until they hit CTRL-D
    65 try:                                                       # 异常
    66     while True:
    67         snippets = list(PHRASES.keys())                    # snippets是由PHRASES字典的键组成的列表
    68         random.shuffle(snippets)                           # 将snippets列表中的元素顺序打乱
    69         
    70         for snippet in snippets:                           # 遍历snippets列表
    71             phrase = PHRASES[snippet]                      # 通过键snippet对应的值
    72             question,answer = convert(snippet,phrase)      # 调用convert函数,完成键值对中字符串的替换,并将函数返回值
    73             if PHRASE_FIRST:                               # 
    74                 question,answer = answer,question          # 将替换后的结果与问题换过来
    75             
    76             print(question)                                # 打印question,表示经过替换的PHRASES字典的键的内容
    77             
    78             input("> ")                                    # 可输入answer中提示的内容来查看对应的类或者方法的结构
    79             print(f"ANSWER:{answer}
    
    ")                  # 打印answer,即question键对应的经过替换的PHRASES字典的值的内容
    80 except EOFError:
    81     print("
    Bye")

    执行过程中,输入:

    1 python oop_test.py english
    有关字符串的内容,可参考:https://www.cnblogs.com/luoxun/p/13257881.html
     
  • 相关阅读:
    Vue.Js(html5) + Java实现文件分片上传
    进程、线程基础知识全家桶,30 张图一套带走
    20 张图揭开「内存管理」的迷雾,瞬间豁然开朗
    面试官:换人!他连 TCP 这几个参数都不懂
    TCP 半连接队列和全连接队列满了会发生什么?又该如何应对?
    实战!我用 Wireshark 让你“看得见“ TCP
    IP 基础知识全家桶,45 张图一套带走
    写了Bug,误执行 rm -fr /*,我删删删删库了,要跑路吗?
    你还在为 TCP 重传、滑动窗口、流量控制、拥塞控制发愁吗?看完图解就不愁了
    硬不硬你说了算!35 张图解被问千百遍的 TCP 三次握手和四次挥手面试题
  • 原文地址:https://www.cnblogs.com/luoxun/p/13399256.html
Copyright © 2011-2022 走看看