创建第一个区块链的小知识

1.python textwrap模块

该模块首先提供了三个便捷的方法:wrap,fill和decent,也提供了TextWrapper类。其中TextWrapper提供了全套的方法,前三个方法只是便捷的使用,因为在内部的运行中也是建立了一个TextWrapper对象。如果程序中需要大量运用这几个方法,最好还是创建TextWrapper比较快一些。

textwrap.wrap(text,[width[,…]])

这个方法是将一个字符串按照width的宽度进行切割,切割后返回list

#-*-coding:utf-8-*- 
import textwrap 
sample_text = '''aaabbbcccdddeeeedddddfffffggggghhhhhhkkkkkkk''' 
sample_text2 = '''aaa bbb ccc ddd eeee ddddd fffff ggggg hhhhhh kkkkkkk''' print sample_text print textwrap.wrap(sample_text,width=5)
print textwrap.wrap(sample_text2,width=5)
执行结果:
aaabbbcccdddeeeedddddfffffggggghhhhhhkkkkkkk
['aaabb', 'bcccd', 'ddeee', 'edddd', 'dffff', 'fgggg', 'ghhhh', 'hhkkk', 'kkkk'] 
['aaa', 'bbb', 'ccc', 'ddd', 'eeee', 'ddddd', 'fffff', 'ggggg', 'hhhhh', 'h kkk', 'kkkk']

看第三个打印的结果,并不是保证了每个list元素都是按照width的,因为不但要考虑到width,也要考虑到空格,也就是一个单词。

textwrap.fill(text[, width[, …]])

这个和上面wrap方法类似,不过返回结果是不一样的

#-*-coding:utf-8-*-
import textwrap 
sample_text = '''aaabbbcccdddeeeedddddfffffggggghhhhhhkkkkkkk''' 
sample_text2 = '''aaa bbb ccc ddd eeee ddddd fffff ggggg hhhhhh kkkkkkk''' 
print sample_text 
print textwrap.fill(sample_text,width=5) 
print textwrap.fill(sample_text2,width=5)
执行结果:
aaabbbcccdddeeeedddddfffffggggghhhhhhkkkkkkk 
aaabb 
bcccd 
ddeee 
edddd 
dffff 
fgggg 
ghhhh 
hhkkk 
kkkk 
aaa 
bbb 
ccc 
ddd 
eeee 
ddddd 
fffff 
ggggg 
hhhhh 
h kkk 
kkkk
textwrap.dedent(text)

这个方法是用来移除不被期望的空白符

#-*-coding:utf-8-*-
import textwrap 
sample_text = '''
    aaabbb
                cccdddee    eedddddfffffggggghhhhhhkkkkkkk''' 
print sample_text 
print textwrap.dedent(sample_text)
执行结果:
    aaabbb
                cccdddee    eedddddfffffggggghhhhhhkkkkkkk

aaabbb
            cccdddee    eedddddfffffggggghhhhhhkkkkkkk

2.在flask中使用jsonify和json.dumps的区别

flask提供了jsonify函数供用户处理返回的序列化json数据,而python自带的json库中也有dumps方法可以序列化json对象。下面就jsonify和json.dumps的区别这一问题简单探讨一下。

分析

jsonify:
在这里插入图片描述
json.dumps:
在这里插入图片描述

Content-Type有区别

jsonify的作用实际上就是将我们传入的json形式数据序列化成为json字符串,作为响应的body,并且设置响应的Content-Type为application/json,构造出响应返回至客户端。jsonify的部分源码如下:

def jsonify(*args, **kwargs):
    if __debug__:
        _assert_have_json()
    return current_app.response_class(json.dumps(dict(*args, **kwargs),
        indent=None if request.is_xhr else 2), mimetype='application/json')

可以看出jsonify实际上也是使用了json.dumps来序列化json形式的数据,作为响应正文返回。indent表示json格式化的缩进,若是Ajax请求则不缩进(因为一般Ajax数据没必要直接展示),否则缩进2格。但想必从第一部分的实验结果我们已经看出来了,使用jsonify时响应的Content-Type字段值为application/json,而使用json.dumps时该字段值为text/html。Content-Type决定了接收数据的一方如何看待数据,如何处理数据,如果是application/json,则可以直接当做json对象处理,若是text/html,则还要将文本对象转化为json对象再做处理

  • 接受参数有区别
    jsonify可以接受和python中的dict构造器同样的参数
    在这里插入图片描述
    而json.dumps比jsonify可以多接受list类型和一些其他类型的参数。但我试了一下,形式为key1=value1,[key2=value2,…]这样的参数是不行的,会报出“TypeError: dumps() takes exactly 1 argument (0 given)”这一错误,而jsonify不会报错并能正常返回数据。

3.幂等性

HTTP/1.1中对幂等性的定义是:一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时等问题除外)。也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同

什么情况下需要保证幂等性

以SQL为例,有下面三种场景,只有第三种场景需要开发人员使用其他策略保证幂等性:

  1. SELECT col1 FROM tab1 WHER col2=2,无论执行多少次都不会改变状态,是天然的幂等。
  2. UPDATE tab1 SET col1=1 WHERE col2=2,无论执行成功多少次状态都是一致的,因此也是幂等操作。
  3. UPDATE tab1 SET col1=col1+1 WHERE col2=2,每次执行的结果都会发生变化,这种不是幂等的。

4. @property与@staticmethod

Python内置有三大装饰器:@staticmethod(静态方法)、@classmethod(类方法)、@property(描述符),其中静态方法就是定义在类里的函数,并没有非要定义的必要;类方法则是在调用类属性、传递类对象时使用;而@property则是一个非常好用的语法糖。@property最大的好处就是在类中把一个方法变成属性调用,起到既能检查属性,还能用属性的方式来访问该属性的作用。
@property应用
让我们先看下@property的应用,其功能1是可定义只读属性,也就是真正意义上的私有属性。实例需求是定义类Person,具有年龄和姓名,要求年龄必须等于18,则代码如下:

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.__age = 18

    @property
    def age(self):
        return self.__age
        
xm = Person('xiaoming')  #定义一个人名小明
print(xm.age)	#结果为18
xm.age = -4	#报错无法给年龄赋值
print(xm.age)

结果如下:

18
Traceback (most recent call last):
	xm.age = 18
AttributeError: can't set attribute

在python中定义只读属性非@property莫属,如果细心留意大部分源码,都跑不了@property的身影。而定义只读属性也很简单:以需要定义的属性为方法名(上例age属性定义为方法),其上装饰内置装饰器@property就ok了。
  @property真正强大的是可以限制属性的定义。往往我们定义类,希望其中的属性必须符合实际,但因为在__init__里定义的属性可以随意的修改,导致很难实现。如我想实现Person类,规定每个人(即创建的实例)的年龄必须大于18岁,正常实现的话,则必须将属性age设为只读属性,然后通过方法来赋值,代码如下:

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.__age = 18

    @property
    def age(self):
        return self.__age

    def set_age(self, age): #定义函数来给self.__age赋值
        if age < 18:
            print('年龄必须大于18岁')
            return
        self.__age = age
        return self.__age
     
     xm = Person('xiaoming', 20)
print(xm.age)
print('----------')
xm.set_age(10)
print(xm.age)
print('----------')
xm.set_age(20)
print(xm.age)

为了便于区分结果,增加了分隔符,结果如下:

18
----------
年龄必须大于18岁
18
----------
20

可以看到,通过方法的确能限制输入,但是不是每个人都记得方法名,有什么简化的方法呢?@property就能很轻松办到,修改代码如下:

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.__age = 18
        
    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, age):
        if age < 18:
            print('年龄必须大于18岁')
            return
        self.__age = age
        return self.__age
xm = Person('xiaoming', 20)
print(xm.age)
print('----------')
xm.age = 10
print(xm.age)
print('----------')
xm.age = 20
print(xm.age)

结果和上图一致。两段代码变化的内容:将set_age修改为age,并且在上方加入装饰器@age.setter。这就是@property定义可访问属性的语法,即仍旧以属性名为方法名,并在方法名上增加@属性.setter就行了。
@staticmethod
一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。
而使用@staticmethod,就可以不需要实例化,直接类名.方法名()来调用。

@staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。
@staticmethod
经常有一些跟类有关系的功能但在运行时又不需要实例和类参与的情况下需要用到静态方法.

5.Flask关于request一些方法和属性的整理

前提:基于纯后端服务,
post 请求 (Content-Type: application/json,)

1.获取未经处理过的原始数据而不管内容类型,如果数据格式是json的,则取得的是json字符串,排序和请求参数一致
c = request.get_data()
2.将请求参数做了处理,得到的是字典格式的,因此排序会打乱依据字典排序规则
c =request.get_json()
3.可以获取未经处理过的原始数据,如果数据格式是json的,则取得的是json字符串,排序和请求参数一致
c = request.data
4.将请求参数做了处理,得到的是字典格式的,因此排序会打乱依据字典排序规则
c = request.json

6.urlparse解析url

parse_url — 解析 URL,返回其组成部分

mixed parse_url ( string $url [, int $component = -1 ] )

本函数解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分。
本函数不是用来验证给定 URL 的合法性的,只是将其分解为下面列出的部分。不完整的 URL 也被接受,parse_url()会尝试尽量正确地将其解析。

参数
url:要解析的 URL。无效字符将使用 _ 来替换。
component:
指定 PHP_URL_SCHEME、 PHP_URL_HOST、 PHP_URL_PORT、 PHP_URL_USER、 PHP_URL_PASS、 PHP_URL_PATH、PHP_URL_QUERY 或 PHP_URL_FRAGMENT 的其中一个来获取 URL 中指定的部分的 string。 (除了指定为PHP_URL_PORT 后,将返回一个 integer 的值)。

返回值
对严重不合格的 URL,parse_url() 可能会返回 FALSE。
如果省略了 component 参数,将返回一个关联数组 array,在目前至少会有一个元素在该数组中。数组中可能的键有以下几种:

  • scheme - 如 http
  • host
  • port
  • user
  • pass
  • path
  • query - 在问号 ? 之后
  • fragment - 在散列符号 # 之后
    如果指定了 component 参数, parse_url() 返回一个 string (或在指定为 PHP_URL_PORT 时返回一个 integer)而不是array。如果 URL 中指定的组成部分不存在,将会返回 NULL。
    example1:
url = 'http://username:password@hostname/path?arg=value#anchor';
print_r(parse_url($url));
echo parse_url($url, PHP_URL_PATH);
Array
(
    [scheme] => http
    [host] => hostname
    [user] => username
    [pass] => password
    [path] => /path
    [query] => arg=value
    [fragment] => anchor
)
/path

example2:

from urllib.parse import urlparse

url = 'https://github.com/search?q=krislp'

parse = urlparse(url)

print(parse)

输出结果:

ParseResult(scheme='https', netloc='github.com', path='/search', params='', query='q=krislp', fragment='')

参考:[1]https://blog.csdn.net/weixin_42681866/article/details/83376484

猜你喜欢

转载自blog.csdn.net/weixin_40108745/article/details/88043337