#434 转载:Python 异步编程与数据库

2020-11-22

这是大神 zzzeek 2015 年发表的一篇文章,详细介绍了关于 SQLAlchemy 与异步编程的一些事情。解答了我关于如何实现异步编程的一些疑惑。
我曾反复阅读这篇文章好多遍,以求能够更加准确地领会到大佬阐述的意思。我认为每个 Python 的使用者都应该阅读阅读。

#433 Golang: cannot assign to struct field xxx in map

2020-11-20
package main

import (
    "fmt"
)

type Person struct {
    FirstName string
    LastName  string
}

func main() {
    // 准备 =========================
    people := make(map[int]Person)
    person := Person{
        FirstName: "John",
        LastName:  "Doe",
    }
    people[1] = person

    // 报错:cannot assign to struct field people[1].FirstName in map
    // people[1].FirstName = "Jim"

    // 方式 1
    p := people[1]
    p.FirstName = "Alice"
    people[1] = p
    fmt.Println(people)
    // map[1:{Alice Doe}]
    fmt.Println(people[1])
    // {Alice Doe}

    // if p, ok := people[1]; ok {
    //  p.Field = 5
    //  people[1] = p
    // }

    // 方式 2
    people2 := make(map[int]*Person)
    people2[1] = &person
    people2[1].FirstName = "Adam"
    fmt.Println(people2)
    // map[1:0xc000060020]
    fmt.Println(people2[1])
    // &{Adam Doe}
}

总之,不能直接通过 key 找到 value(struct),然后修改其中的一个字段。

#432 Java 现状

2020-11-11

谷歌 Java 趋势

Oracle Java SE Support Roadmap

Release GA Date Premier Support Until Extended Support Until
7 (LTS) July 2011 July 2019 July 2022
8 (LTS) March 2014 March 2022 December 2030
9 September 2017 March 2018 -
10 March 2018 September 2018 -
11 (LTS) September 2018 September 2023 September 2026
12 March 2019 September 2019 -
13 September 2019 March 2020 -
14 March 2020 September 2020 -
15 September 2020 March 2021 -
16 March 2021 September 2021 -
17 (LTS) September 2021 September 2026 September 2029
18 March 2022 September 2022 -
19 September 2022 March 2023 -
20 March 2023 September 2023 -
21 (LTS) September 2023 September 2028 September 2031

PS:Java 9 开始引入了新的模块机制,标准库结构。

PS: 2021 年 Java 17 发布时,Oracle 宣布以后每两年一个 LTS 版本,也就是说下一个 LTS 版本是 21 而非 23。

参考资料与拓展阅读

#431 BOM 头的研究

2020-11-03

BOM 是 Byte Order Mark 的缩写,代表一个 Unicode 字符 FEFF
Windows 系统下的很多软件就用 BOM 字符作为 Magic Number, 用来确认文件的字符编码和字节顺序。

#430 字符编码

2020-11-01

从原理上来讲,我们的计算机其实只认识数字(要不然为什么叫做计算机),确切的说是 0 和 1,我们的文字信息存放在计算机中也是以数字形式存在。
所谓字符编码就是字符和数字之间的对应关系和转换规则。

#429 “锟斤拷” 到底是个啥?

2020-11-01

img

手持两把锟斤拷,
口中疾呼烫烫烫。
脚踏千朵屯屯屯,
笑看万物锘锘锘。

开发者经常这样调侃编码问题:手持两把锟斤拷,口中疾呼烫烫烫。

程序员都知道字符编码,比如 ASCII,GBK,UTF-8,那肯定能理解这些神奇的 “乱码” 出现的原因,肯定是某些地方没有正确处理编码。

那为什么总是能看见 锟斤拷烫烫烫呢?其背后隐藏更深的原因是啥?

#428 Golang 数据类型

2020-10-31

基础类型:

  • Boolean types (bool)
  • Numeric types
  • String types (string)

复合类型:

  • Array types ([len]Type)
  • Slice types ([]Type)
  • Struct types (struct)
  • Map types (map[KeyType]ValueType{})

特殊类型:

  • Pointer types (*Type) 指针
  • Function types (func) 函数
  • Interface types (interface) 接口
  • Channel types (chan) 通道

引用类型

基础类型 + Array + Struct 不是引用类型,其他几种(Slice + Map + Pointer + Function + Interface + Channel)都是引用类型,函数传参的时候需要记住这一点。

数值

uint8       the set of all unsigned  8-bit integers (0 to 255)
uint16      the set of all unsigned 16-bit integers (0 to 65535)
uint32      the set of all unsigned 32-bit integers (0 to 4294967295)
uint64      the set of all unsigned 64-bit integers (0 to 18446744073709551615)

int8        the set of all signed  8-bit integers (-128 to 127)
int16       the set of all signed 16-bit integers (-32768 to 32767)
int32       the set of all signed 32-bit integers (-2147483648 to 2147483647)
int64       the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)

float32     the set of all IEEE-754 32-bit floating-point numbers
float64     the set of all IEEE-754 64-bit floating-point numbers

complex64   the set of all complex numbers with float32 real and imaginary parts
complex128  the set of all complex numbers with float64 real and imaginary parts

byte        alias for uint8
rune        alias for int32

// 实现相关:
uint     either 32 or 64 bits
int      same size as uint
uintptr  an unsigned integer large enough to store the uninterpreted bits of a pointer value

声明

var foo int

var foo int = 1

foo := 1

const foo = 1

const foo int = 1

注意:只有基础类型可以声明为常量。

#427 常见药品名称

2020-10-30

经常使用,或者在书本上、网络上、电视广告上,或其他日常生活场景中,经常接触到的药品。

#426 RQ 任务队列

2020-10-19

RQ (Redis Queue) is a simple Python library for queueing jobs and processing them in the background with workers. It is backed by Redis and it is designed to have a low barrier to entry. It can be integrated in your web stack easily.

翻译:RQ (Redis Queue)是一个简单的 Python 库,用于将作业排队并在后台与 worker 一起处理它们。它由 Redis 支持,其设计具有较低的进入门槛。它可以很容易地集成到您的 web 堆栈中。

This project has been inspired by the good parts of Celery, Resque and this snippet, and has been created as a lightweight alternative to existing queueing frameworks, with a low barrier to entry.

示例

启动 worker 进程:

rq worker
rq worker --url redis://:secrets@example.com:1234/9

项目中添加任务:

from redis import Redis
from rq import Queue

# 队列
q = Queue(connection=Redis())

# 添加任务
from my_module import count_words_at_url
result = q.enqueue(count_words_at_url, 'http://nvie.com')

# 关于重试
from rq import Retry
# 失败之后立即重试
queue.enqueue(say_hello, retry=Retry(max=3))
# 失败之后间隔指定时间重试
queue.enqueue(say_hello, retry=Retry(max=3, interval=[10, 30, 60]))

获取结果:


参考资料与拓展阅读

#425 Python 删除文件

2020-09-27

平时删除文件都是 os.unlink 和 os.remove 中随便选一个,今天突然想看看这两个方法有什么不一样。

remove 和 unlink 实际上来自 Modules/posixmodule.c
可以看到这两个方法实际上相同。

/*[clinic input]
os.remove = os.unlink
Remove a file (same as unlink()).
If dir_fd is not None, it should be a file descriptor open to a directory,
  and path should be relative; path will then be relative to that directory.
dir_fd may not be implemented on your platform.
  If it is unavailable, using it will raise a NotImplementedError.
[clinic start generated code]*/

static PyObject *
os_remove_impl(PyObject *module, path_t *path, int dir_fd)
/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
{
    return os_unlink_impl(module, path, dir_fd);
}

Python 3 的 Path 对象中也有一个 unlink 方法(pathlib.Path.unlink):

def unlink(self, missing_ok=False):
    """
    Remove this file or link.
    If the path is a directory, use rmdir() instead.
    """
    try:
        os.unlink(self)
    except FileNotFoundError:
        if not missing_ok:
            raise

顺便对删除目录做一个整理:

# os.remove(path: StrOrBytesPath, *, dir_fd: int | None = ...)
# os.unlink(path: StrOrBytesPath, *, dir_fd: int | None = ...)

os.mkdir(path: StrOrBytesPath, mode: int = ..., *, dir_fd: int | None = ...)
os.rmdir(path: StrOrBytesPath, *, dir_fd: int | None = ...)

os.makedirs(name: StrOrBytesPath, mode: int = ..., exist_ok: bool = ...)
os.removedirs(name: StrOrBytesPath)

pathlib.Path.rmdir -> os.rmdir

shutil.rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None)