学习笔记

0206-underscore-Python

Posted on 2022-02-06,10 min read
封面图

Function

bind

错误函数用法示例:

'use strict';
var s = ' Hello  ';
s.trim();
// 输出'Hello'
var fn = s.trim;
fn();
// Uncaught TypeError: String.prototype.trim called on null or undefined

fn()取代s.trim(), 上述方法的fn()传入的this指针是undefined, 应该这么用:

var s = ' Hello  ';
var fn = s.trim;
// 调用call并传入s对象作为this:
fn.call(s)
// 输出Hello

bind()可以将s绑定到fn()this上, 修复之前的错误:

var s = ' Hello  ';
var fn = _.bind(s.trim, s);
fn();

partial

partial()创建偏函数;
创建pow2N(n)实现Math.pow(2,n);

'use strict';
var pow2N = _.partial(Math.pow, 2);
pow2N(3); // 8
pow2N(5); // 32
pow2N(10); // 1024

创建cube(x),计算x^3,可以用_作占位符,固定住第二个参数:

var cube = _.partial(Math.pow, _, 3);
cube(3); // 27
cube(5); // 125
cube(10); // 1000

memoize

memoize()自动缓存函数计算的结果:

var factorial = _.memoize(function(n) {
    console.log('start calculate ' + n + '!...');
    var s = 1, i = n;
    while (i > 1) {
        s = s * i;
        i --;
    }
    console.log(n + '! = ' + s);
    return s;
});
// 第一次调用:
factorial(10); // 3628800
// 注意控制台输出:
// start calculate 10!...
// 10! = 3628800
// 第二次调用:
factorial(10); // 3628800
// 控制台没有输出

但是factorial(9);仍然会重新计算, 可以利用递归调用实现阶乘的逐步缓存:

var factorial = _.memoize(function(n) {
    console.log('start calculate ' + n + '!...');
    if (n < 2) {
        return 1;
    }
    return n * factorial(n - 1);
});
factorial(10); // 3628800
// 输出结果说明factorial(1)~factorial(10)都已经缓存了:
// start calculate 10!...
// start calculate 9!...
// start calculate 8!...
// start calculate 7!...
// start calculate 6!...
// start calculate 5!...
// start calculate 4!...
// start calculate 3!...
// start calculate 2!...
// start calculate 1!...
factorial(9); // 362880
// console无输出

once

once()保证某个函数执行且仅执行一次:

var register = _.once(function () {
    alert('Register ok!');
});
// 测试效果:
register();
register(); //之后无弹窗
register();

delay

'use strict';
// 2秒后调用alert():
_.delay(alert, 2000);

延迟调用的函数有参数:

var log = _.bind(console.log, console);
_.delay(log, 2000, 'Hello,', 'world!');
// 2秒后打印'Hello, world!':

Python

字符串编码

ord()获取字符的整数表示,chr()把编码转换为对应的字符:

>>> ord('A')
65
>>> ord('中')
20013
>>> chr(66)
'B'
>>> chr(25991)
'文'

用十六进制这么写str

>>> '\u4e2d\u6587'  #4e2d>20013>'中'
'中文'

字符串类型为str,在网络上传输或保存到磁盘需要转化为字节为单位的bytes数据,用带b前缀的单引号或双引号表示:'ABC'b'ABC'不同。
encode()与decode()
str通过encode()方法可以编码为指定的bytes

>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

bytes变为str,需要用decode():

>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'

如果bytes中只有一小部分无效的字节,可以传入errors='ignore'忽略错误的字节:

>>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
'中'

len()
计算str的字符数用len():

>>> len('ABC')
3
>>> len('中文')
2

如果换成bytes就计算字节数:

>>> len(b'ABC')
3
>>> len(b'\xe4\xb8\xad\xe6\x96\x87')
6
>>> len('中文'.encode('utf-8'))
6

占位符
x% ——十六进制整数;
%s永远起作用,它会把任何数据类型转换为字符串:

>>> 'Age: %s. Gender: %s' % (25, True)
'Age: 25. Gender: True'
#format(), 占位符{0}、{1}…
>>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
'Hello, 小明, 成绩提升了 17.1%'

f-string, 若包含{xxx},就会以对应的变量替换:

>>> r = 2.5
>>> s = 3.14 * r ** 2
>>> print(f'The area of a circle with radius {r} is {s:.2f}')
The area of a circle with radius 2.5 is 19.62

除了特殊需求,牢记仅使用UTF-8编码。

list与tuple

list

>>> classmates = ['Michael', 'Bob', 'Tracy']
>>> classmates
['Michael', 'Bob', 'Tracy']

len()函数可以获得list元素的个数:len(classmates) //3

>>> classmates[0]
'Michael'
>>> classmates[1]
'Bob'
>>> classmates[2]
'Tracy'
>>> classmates[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

访问倒数第n个元素:

>>> classmates[-1]
'Tracy'
>>> classmates[-2]
'Bob'
>>> classmates[-3]
'Michael'
>>> classmates[-4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

追加元素

#从末尾追加
>>> classmates.append('Adam')
>>> classmates
['Michael', 'Bob', 'Tracy', 'Adam']
#按索引插入
>>> classmates.insert(1, 'Jack')
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy', 'Adam']
#删除末尾
>>> classmates.pop()
'Adam'
>>> classmates
['Michael', 'Jack', 'Bob', 'Tracy']
#索引弹出
>>> classmates.pop(1)
'Jack'
>>> classmates
['Michael', 'Bob', 'Tracy']
#替换
>>> classmates[1] = 'Sarah'
>>> classmates
['Michael', 'Sarah', 'Tracy']

list套list——多维数组

>>> s = ['python', 'java', ['asp', 'php'], 'scheme']
>>> len(s)
4

tuple
理解“指向不变”:

>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])

条件判断

if <条件判断1>:
    <执行1>
elif <条件判断2>:
    <执行2>
elif <条件判断3>:
    <执行3>
else:
    <执行4>

循环

for...in...
for x in ...循环就是把每个元素代入变量x,然后执行缩进块的语句。

names = ['Michael', 'Bob', 'Tracy']
for name in names:
    print(name)

range(101)生成0-100的整数序列.
while循环

sum = 0
n = 99
while n > 0:
    sum = sum + n
    n = n - 2
print(sum)

dict与set

dict在其他语言中Map对象。
总述: 列表 list[] 、元组 tuple() 、字典 dict{ key : value } 、无序不重复元素集合 set(list[]) ,后两者的key为不可变对象, 元组元素"指向"不可变。
对于 不变对象 来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。
重复元素在set中自动被过滤:

>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}

添加元素到set中:

>>> s.add(4)
>>> s
{1, 2, 3, 4}
>>> s.add(4)
>>> s
{1, 2, 3, 4}

删除元素:

>>> s.remove(4)
>>> s
{1, 2, 3}

set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:

>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}

调用函数

max()函数可以接受任意多个参数, 并返回最大的数:

>>> max(1, 2)
2
>>> max(2, 3, 1, -5)
3

定义函数

空函数

def nop():
    pass

pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来, 也可以放到其他语句中:

if age >= 18:
    pass

参数检查
数据类型检查可以用内置函数isinstance()实现:

def my_abs(x):
    if not isinstance(x, (int, float)):
        raise TypeError('bad operand type')
    if x >= 0:
        return x
    else:
        return -x

返回多个值
游戏中经常需要从一个点移动到另一个点,给出坐标、位移和角度,就可以计算出新的坐标:

import math

def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny

Python函数返回的仍然是单一值:

>>> r = move(100, 100, 60, math.pi / 6)
>>> print(r)
(151.96152422706632, 70.0)

函数的参数

明天


下一篇: 0205-underscore→

loading...