Python PK JS 原生实现一些功能

这是我参与更文挑战的第2天,活动详情查看: 更文挑战

前言

近来,项目上,遇见了用Python编写的发布脚本,瞬间就被她迷人的眼神和身段迷上了。近来几天一直追随她,越发的喜爱。喜爱之余,拿她与我的前任(JS)最了一些对比。
当然纯语法的对比,那太单调。这里我就实现一些基本的功能来对比两者语法上的一些差异。

源码都放在github上面了: Python PK JS

新欢(Python) VS 前任(JS)

字符串截取

Python一点都不废话,直接[:]搞定。
Python

text = "你们都是坏人啊"

print(text[0:5])  # 你们都是坏
复制代码

JS

const print = console.log

const text = "你们都是坏人啊"

print(text.substring(0,5))  // 你们都是坏
复制代码

时间格式化

很明显,在没有借助第三方库的前提下,JS格式化时间的能力还是比较弱的。当然有些人会说,JS的
Date.prototype.toLocaleString 能做到一定的格式化,但毕竟能力有限。

还有字符串的填充问题,1月应该显示为 01。 而这种能力居然在Python时间格式化函数里面是现成的。

import time

def format(date):
    return time.strftime("%Y-%m-%d %H:%M:%S", date)

print(format((2020, 1, 1, 1, 1, 1, 0, 0, 0))) # 2020-01-01 01:01:01
复制代码

function padNum(num, length = 2, ch = "0") {
    return `${num}`.padStart(length, ch);
}

function formatDate(date) {
    const d = new Date(date);
    const fullYear = d.getFullYear();
    const month = padNum(d.getMonth() + 1)
    const day = padNum(d.getDate())
    const h = padNum(d.getHours())
    const m = padNum(d.getMinutes())
    const s = padNum(d.getSeconds())

    return `${fullYear}-${month}-${day} ${h}:${m}:${s}`
}

console.log(formatDate(new Date(2020, 0, 1, 1, 1, 1))); // 2020-01-01 01:01:01

复制代码

对象属性设置和遍历

Python把JS里面的对象叫做字典。
采用类似对象字面量形式申明的时候,属性名还必须是类似JSON的形式,必须以"包起来。
设置值的时候不能像JS那样 obj.name,而必须是obj["name"]
遍历自身属性的时候,比JS方便一些,而不用借助外力。

Python

obj = {
    "name": "Tom",
    "age": 10,
    "weight": 60,
    "height": 100
}

obj["name"] = "Tom +"
obj["age"] = 100


print(obj)
# 输出所有的属性键
print("keys:", obj.keys())

print()
print("----------------------")
for k in obj.keys():
    print("key:", k, " value:", obj[k])
复制代码
const print = console.log
const obj = {
    name: "Tom",
    age: 10,
    weight: 60,
    height: 100
}

obj.name = "Tom +";
obj["age"] = 100;

print(obj);

// 输出所有的属性键
print("keys:", Object.keys(obj))

for(let k in obj){
    print("key:", k, " value:", obj[k])
}
复制代码

正则替换和分组

Python中的正则替换使用的是re.sub,二这个能力在js里面是字符串自带的能力。虽然Python里面的字符串也有replace方法,是纯字符串的替换。

至于分组,Python这边的体验好太多了。

import re

# 替换#后面的内容为空
text = "158000000#手机号码";
print(re.sub("#.*$","", text)); #158000000

# 分组
dateText = "2018-01-06";
reDate = re.compile("(\d{4})-(\d{1,2})-(\d{1,2})");
print(reDate.search(dateText).groups()) # ('2018', '01', '06')

复制代码
const print = console.log;
// 替换#后面的内容为空
const text = "158000000#手机号码";
print(text.replace(/#.*$/,"")); //158000000

// 分组
dateText = "2018-01-06";
execArray = /(\d{4})-(\d{1,2})-(\d{1,2})/.exec(dateText)
print(execArray)  // ['2018-01-06','2018','01','06',index: 0,input: '2018-01-06', groups: undefined ]

// /(\d{4})-(\d{1,2})-(\d{1,2})/.exec(dateText)
// print(":", RegExp.$1, RegExp.$2, RegExp.$3)

复制代码

数组

数组增加,删除,查找

Python里面对应的是list.
Python整体的语法还是相对简单一点,尤其是可以直接根据某个值删除。
JS里面的数组内置的方法更加的多,功能也相对强大一些。 Python有一个单独的array模块来增强。

arr = ["1", 2, "1", "3"];

# 尾部增加
arr.append(10000);
print(arr); # ['1', 2, '1', '3', 10000]

# 头部增加
arr.insert(0, -10000);
print(arr); # [-10000, '1', 2, '1', '3', 10000]

# 查找值的位置
index = arr.index(10000);
print("index", index) # index 5

# 修改
arr[2] = 3;
print(arr); # [-10000, '1', 3, '1', '3', 10000]

# 删除
arr.remove("1") 
print(arr); # [-10000, 3, '1', '3', 10000]

# 删除
arr.remove("1") 
print(arr); # [-10000, 3, '3', 10000]
复制代码
const print = console.log
const arr = ["1", 2, "1", "3"];

// 尾部增加
arr.push(10000);
print(arr); // [ '1', 2, '1', '3', 10000 ]

// 头部增加
arr.unshift(-10000)
print(arr);  // [ -10000, '1', 2, '1', '3', 10000 ]

// 查找值的位置
let index = arr.indexOf(10000)
print("index", index) // index 5

// 修改
arr[2] = 3;
print(arr); // [ -10000, '1', 3, '1', '3', 10000 ]

// 删除
index = arr.indexOf("1");
arr.splice(index, 1) 
print(arr); // [ -10000, 3, '1', '3', 10000 ]

// 删除
index = arr.indexOf("1");
arr.splice(index, 1) 
print(arr); // [ -10000, 3, '3', 10000 ]

复制代码

数组填充

Python自带的range这里就很亮眼。
还有这酷酷的 推导式 [m for m in range(1, 101, 1)]

# arr = list(range(1, 101, 1));
arr = [m for m in range(1, 101, 1)]
print(arr) # [1,2,3 ......, 100]
复制代码
const print = console.log;
const arr = Array.from({
    length: 100
}, (v, i) => {
    return i + 1
});

print(arr); // [1,2,3 ......, 100]
复制代码

遍历文件夹和获取所有文件

遍历文件夹

Python是两层for循环,但是非常直接。
JS这边是传统的递归。

import os
import sys

def walk(dir):
    for root, dirs, files in os.walk(dir):
        for file in files:
            print(os.path.join(root, file))
        for dir in dirs:
            print(os.path.join(root, dir))


currentDir = os.path.split(os.path.realpath(sys.argv[0]))[0]
walk(currentDir);
复制代码
const path = require("path");
const fs = require("fs");

function walk(root) {
    const dirs = fs.readdirSync(root);
    dirs.forEach(dir => {
        const fullPath = path.join(root, dir);
        const sta = fs.statSync(fullPath);
        if(sta.isFile()){
            return console.log(fullPath);
        }
        console.log(fullPath);
        walk(fullPath);
    });
}

walk(__dirname);

复制代码

获取文件夹全部文件路径

哇,采用内置的glob一气呵成。
其实nodejs也是有相关模块的 glob,不过那是第三方的库了。

import os
import glob
import sys

def getFiles(dir):
    return glob.glob("%s/**/*.*" % (dir), recursive=True)


currentDir = os.path.split(os.path.realpath(sys.argv[0]))[0]
print("currentDir", currentDir)
files = getFiles(currentDir)
print(files)

复制代码
const path = require("path");
const fs = require("fs");

function getFiles(root, files) {
    const dirs = fs.readdirSync(root);
    dirs.forEach(dir => {
        const fullPath = path.join(root, dir);
        const sta = fs.statSync(fullPath);
        if(sta.isFile()){
            return files.push(fullPath);
        }
        getFiles(fullPath, files);
    });

    return files;
}

const files = [];
getFiles(__dirname, files);
console.log(files);


复制代码

网络请求

下面发送https请求获取百度首页的内容, Python使用内置库并不轻松。
如果发送的是http请求,Python会简单很多。
这里我发现一个很有意思的问题,Python和NodeJS发送的是get请求,但是返回的结果却不同。
有哪位要是知道原因和更多细节,麻烦请帮忙解惑。

import urllib.request
import urllib.parse
import os
import sys
import ssl

currentDir = os.path.split(os.path.realpath(sys.argv[0]))[0];

headers = {    
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36",
}

context = ssl._create_unverified_context()
request = urllib.request.Request('https://www.baidu.com', headers=headers)

res = urllib.request.urlopen(request, context=context)
html = res.read().decode('utf-8')

with open(os.path.join(currentDir, "./_py_baidu.html"), mode="w", encoding="utf-8") as f:
    f.write(html)

复制代码
const https = require('https');
const fs = require("fs");
const path = require("path");

https.get('https://www.baidu.com', (resp) => {
    let data = '';

    resp.on('data', (chunk) => {
        data += chunk;
    });
    resp.on('end', () => {
        console.log("data", data);
        fs.writeFileSync(path.join(__dirname, "./_js_baidu.html"), data);
    });
}).on("error", (err) => {
    console.log("Error: " + err.message);
});
复制代码

随机数

Python内置的random相当的强大。
JS其实也可以借助三角函数等来随机生成,爽感当然差一些。 虽然可以借助第三方random

import random

# 0-1随机数
print(random.random())

# 1-10随机整数
print(random.randint(1, 10))

# 随机偶数
print(random.randrange(0, 1000, 2))

# 随机浮点数
print(random.uniform(0.1, 3.6))

# 权重相等,选择3个
print(random.choices([1, 2, 3, 4, 5], [1, 1, 1, 1, 1], cum_weights=None, k=3))

复制代码
const print = console.log;

function randInt(min, max) {
    return Math.floor(Math.random() * (max - min)) + min
}

function rand(min, max) {
    return Math.random() * (max - min) + min;
}

// 0-1之间随机数
print(Math.random())

// 1-10之间随机整数
print(randInt(1, 10))

// 0-1000之间 随机偶数
let num = randInt(0, 1000);
num = num % 2 === 0? num : num -1;
print(num)

// // 随机浮点数
print(rand(0.1, 3.6))

// 权重相等,选择3个
// 难搞。。。。。 
复制代码

异常捕获

Python的异常捕获更直接和好懂一些, 而JS得额外通过错误的类型判断,再进行进一步的处理。
Python也是可以通过isinstance来进一步处理的。

try:
    raise TypeError("类型错误");
    open(".../xxxxxx.ts")
except IOError as ioe:
    print("io error", ioe)
except TypeError as te:
    print("type error", te);
except Exception as e:
    print("common error", e.args)
finally:
    print("执行完毕")

复制代码
const fs = require("fs");

const print = console.log;
try {

    throw new TypeError("无效的类型")
    fs.openSync("../sdasdas/x.ts")

} catch (err) {
    if (err instanceof TypeError) {
        print("type error", err)
    } else if (err instanceof Error) {
        print("common error", err)
    }
}


复制代码

类继承

JS的类继承,更加容易理解。和Java, C#等无太大区别。
Python的类,都是带着self奔跑的, 构造函数是 __init__。每个方法第一个参数也是self

class Animal():
    def __init__(self, sex):
        self.sex = sex;
    def eat(self):
        print("eat");
    def getSex(self):
        print("sex", self.sex)

class Human(Animal):
    def __init__(self, sex):
        super().__init__(sex)
    def walk(self):
        print("walk")

human = Human(1);
human.getSex();
human.eat();
human.walk();
复制代码

const print = console.log

class Animal {
    constructor(sex) {
        this.sex = sex;
    }
    getSex() {
        print("sex", this.sex);
    }
    eat() {
        print("eat")
    }
}


class Human extends Animal {
    constructor(sex) {
        super(sex)
    }
    walk() {
        print("walk");
    }
}

var human = new Human(1, 0);
human.getSex();
human.eat();
human.walk();


复制代码

其他有趣的

print(1 == "1")  # False

print([1] + [2])  # [1,2]

print([1, 2, 3] == [1, 2, 3])  # True

print(3 > 2 > 1) # True

复制代码
const print = console.log;

print(1 == "1") // true

print([1] + [2]) // 12

print([1, 2, 3] == [1, 2, 3]) // false

print(3 > 2 > 1); // false
复制代码

引用

python 与 javascript 简单对比

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享