python写文字方法_Transcrypt: 用Python写js的方法

Transcrypt是一个很有意思的工具:

它让你告别手写繁复的JavaScript代码,使用相对简明清晰的Python代替这一工作。

之后使用这个工具,可以把Python编写的代码转换成JavaScript。

1. 为什么不直接写JavsScript?

JavaScript本身不算是很难的编程语言,但还是有很多不便之处。这里只能举几个例子:

1.1 js的模块化问题。

想要实现一个很复杂的js程序,一般要考虑将不同的功能拆分成模块,然后各自完成各自的任务。

然而,js本身没有什么方式可以做到这一点:

要么在浏览器或者NodeJS中,使用require这样的方案(”AMD”—-模块异步加载)(浏览器还需要额外加载require.js),

要么使用各种打包工具(CommonJS—-规定了通用的模块定义方式),根据模块各部分代码相互关系,将所有的代码打包进一个巨大的文件。

Transcrypt支持Python的模块机制(import语法),效果上最后还是生成一个打包的代码文件,但使用起来,比CommonJS要清晰一些。

1.2 缺乏对class这样的关键字的支持

JavaScript虽然算是一种基于对象的语言—-JavaScript中包括数字、字符串等都是对象,

但又没有办法通过class来自己声明一个对象。

这就导致不同的程序员,会采用不同的方案来构建对象。比如有使用Object的:

var owl = {};

owl.color = "white";

owl.category = "Bubo bubo";

owl.eat = function(){ ... };

或者改写一个函数,增加各种attributes:

function Owl(){

var self = this;

this.color = "white";

this.category = "Bubo bubo";

this.eat = function(){ ... };

return this;

}

var owl = new Owl();

1.3 缺乏语法糖,代码复杂

Python简洁的语法,很多得益于丰富的语法糖:

很简洁的几句话就可以实现复杂的功能,而JavaScript则可能要从头开始写一系列代码。

举几个例子:

a) 使用给定的值生成一个字符串

output = """My name is {name}, I'm {age} years old.

My favourite fruit is {favourite}.""".format({

"favourite": "banana",

"name": "Alice",

"age": 18,

})

console.log(output)

这也是一个简单的例子,如何套用模板,将数据转换成供显示的文本。js的解决方案就复杂许多:

首先,js是不支持带有换行的字符串变量的。所以我们不能用Python"""..."""这种语法,指定一个带有换行的字符串。

其次,也不能在js的字符串中定义占位符,然后用数据填充,所以要自行断开字符串,将数据与字符串合并。

看起来结果就是:

var data = {

"favourite": "banana",

"name": "Alice",

"age": 18,

};

var output = "My name is" + data.name + ", I'm" + data.age + "years old.\n";

output += "My favourite fruit is" + data.favourite + ".";

console.log(output);

即使看上去代码量差不多,这样做还是有一个缺点:

如果需要修改模板,使用Python,只要将带有占位符的字符串换掉就可以了(比如字符串在单独的模板文件中予以定义),

但使用js,就需要具体修改带有逻辑运算符的代码。这样就很不直观,容易出错。

b) 根据已有数据生成一个新的数组

假设我们有一个数组[-2, -1, 0, 1, 2, 3, 4],想列出这个数组中大于0的各个数字的平方。

使用js的思路,是新建一个数组,然后遍历原数组,检查各项是否大于0, 如果是,将结果记录到新的数组:

var original = [-2, -1, 0, 1, 2, 3, 4];

var result = [];

for(var i=0; i

if(original[i] > 0){

result.push(Math.pow(original[i], 2));

}

}

Python则简单很多。Python支持在构建list的时候,指定条件,并使用表达式指定要放入list的值:

original = [-2, -1, 0, 1, 2, 3, 4]

result = [each ** 2 for each in original if each > 0]

1.4 复杂的异步编程

JavaScript的另一个令人诟病的问题,是在调用一系列异步调用时难以组织代码。

实际应用中,无论NodeJS还是浏览器,都要遇到各种异步调用的代码。

假设我们有3个函数:

readFile用于读取一个文件;

encrypt用于加密数据;

upload用于将数据上传到服务器。

这三个函数都是异步调用的。

传统的方式,一般是在实际完成功能需要的参数之外,这些函数还接受一个callback(回调函数)作为输入。

这样调用上述函数之后,他们会立刻返回,并不耽误时间。然后当函数对应的后台任务完成时,再呼叫callback,传入结果。

比如这样看,可以假设readFile的用法是readFile(filename, callback)。

这个函数接受一个filename作为要读取的文件名,然后在读取完毕时呼叫callback函数,传入读取结果。

实际调用时,要写成:

readFile("/path/to/somefile", function(err, data){

if(err){

...

return; // 如果读取文件出错

}

// 否则读取文件成功,继续做下一步的事情

});

假如我们想在读取文件后,将文件内容加密,就要在上述代码的读取成功处,

加上对encrypt=encrypt(data, callback)函数的调用。于是代码就成了这个样子:

readFile("/path/to/somefile", function(err, data){

if(err){

...

return; // 如果读取文件出错

}

// 读取文件成功,加密data

encrypt(data, function(err, ciphertext){

if(err){

...

return; // 加密失败

}

// 加密文件成功,继续做别的事情

});

});

如果进一步,想在加密之后,将密文上传到服务器,整个代码就……

readFile("/path/to/somefile", function(err, data){

if(err){

...

return; // 如果读取文件出错

}

// 读取文件成功,加密data

encrypt(data, function(err, ciphertext){

if(err){

...

return; // 加密失败

}

// 加密文件成功,密文是ciphertext,将它上传

upload(ciphertext, function(err, result){

if(err){

...

return; // 上传失败

}

// 上传成功

});

});

});

很多时候,要完成的工作都是上面这样一连串的。

js的回调机制,就很容易引入如上所示不断嵌套的代码,让结果变得十分难看,所谓的回调地狱。

为了解决这个问题,JavaScript引入了Promise机制。

这样每个函数就都返回一个Promise对象。

Promise对象支持使用.then()这样的方法,将流程串联起来:

readFile("/path/to/somefile")

.then(encrypt)

.then(upload)

.catch(function(err){

...

// 如果上面某一步出错的话,就直接跳到这里

});

这样简明了许多。

Transcrypt在Promise机制的基础上,结合了Python 3引入的async和await语法,让上面的过程变得更加直观:

async def encryptFileAndUpload(path):

try:

data = await readFile(path)

ciphertext = await encrypt(data)

await upload(ciphertext)

except:

# 处理错误encryptFileAndUpload("/path/to/somefile")

使用await,这些异步的调用又可以写成一系列按顺序完成的代码,而不失对各步的控制,思路清晰很多。

2. 如何使用Transcrypt?

2.1 安装和调用

Transcrypt可以通过pip安装:

$ sudo pip install transcrypt

安装后,直接在命令行调用就可以了,例如,

$ transcrypt main.py

可以将main.py转换成js文件。

类似Python 3在执行代码前会在__pycache__目录中放置Python字节码那样,

transcrypt会将转换后的文件放到相应的__javascript__目录。

如果要求转换的是main.py,则在__javascript__/中,一般会有如下文件:

main.mod.js,这是仅仅包含main.py各行代码相应js转译的文件。

这个文件中会用很多transcrypt的函数“包装”输入的Python代码,但基本上是一对一的对照,

因此可供用户检查代码是否有问题等。

main.js,这是将main.py转译为js,并嵌入transcrypt本身需要的js代码,打包而成的文件。

这个文件可以独立嵌入到网页了。

main.min.js。如果见到这个文件,说明transcrypt还进行了代码压缩,这个文件应该也可以单独运行。

代码压缩(minify)需要很多运算,耗费时间,在开发程序时不方便。可以使用-n参数,跳过这一步:

$ transcrypt -n main.py

这样就可以只生成main.js。

2.2 一些坑

Python和Javascript毕竟是两种语言,虽然transcrypt可以在很大程度上将前者翻译为后者,

但有些两种语言内在的不一致,决定了编程时还需要注意许多坑。

在Transcrypt官网的文档中,详细列明了各种坑和其理由。一定要仔细阅读。

2.2.1 类的继承,方法的重载

在Python中,定义基类和子类,是很方便的事情,有时候这种编程方式会节约大量时间。

在transcrypt中,可以使用类的继承,但必须在转译时,于命令行使用-e6选项。

这样生成的代码为ECMAScript 6代码,才可以启用这样的诸多功能。

重载Python的类,自定义诸如__str__,__getattr__或__setattr__这样的方法,

可以编写出非常简明的程序。例如一个模板程序:

class Template:

def __init__(self):

self.__kv = {}

def __str__(self):

return """Welcome to {sitename}!""".format(self.__kv)

def __setattr__(self, key, value):

self.__kv[key] = value

t = Template()

t.sitename = "NeoAtlantis"

print(str(t)) # 输出 Welcome to NeoAtlantis!

这个程序定义的Template类,只需要像操作一般的类那样给它的属性赋值,

然后用str函数令其生成文本即可。这种用法非常直观,但也必须在启用了ECMAScript 6转译后才能利用。

2.2.2 特殊的方法名称

如果要在python中调用一个js模块(比如jQuery的$.get)的get方法,直接调用会出现错误。

根据transcrypt文档的解释,这是因为在python中,get本身具有特定的用途,

故须使用py_get与js_get区别调用python内部和原生js的get方法。

同理,对于set方法也有类似的规定。

2.2.3 __pragma__: 很多特性的开关

transcrypt提供了一个__pragma__函数,可以在程序中微调转译时的行为。

例如,要在python代码中调用jQuery,不能直接使用$变量,因为$并不是一个规范的Python变量名。

这时,就要用__pragma__为$定义一个别名:

__pragma__("alias", "S", "$")

之后,就可以在程序中用S代替$来调用jQuery了。

__pragma__能进行的调节有许多。

很多情况下,Python本身允许的特性,transcrypt出于效率考虑默认不支持,便需要通过这一函数启用。请读者务必参考文档。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第5章 Python 数字图像处理(DIP) - 图像复原与重建8 - 估计噪声参数

标题估计噪声参数估计噪声参数 周期噪声的参数通常是通过检测图像的傅里叶谱来估计的。 只能使用由传感器生成的图像时,可由一小片恒定的背景灰度来估计PDF的参数。 来自图像条带的数据的最简单用途是,计算灰度级的均值和方差。考虑由SSS表示的一个条…

python 随机获取数组元素_Python创建二维数组的正确姿势

List (列表)是 Python 中最基本的数据结构。在用法上,它有点类似数组,因为每个列表都有一个下标,下标从 0 开始。因此,我们可以使用 list[1] 来获取下标对应的值。如果我们深入下列表的底层原理&#xff0c…

Qt学习笔记1

1.Qt引用API时,QString到LPCWSTR的转换: ::GetPrivateProfileIntW(QString(tr("相关设置")).utf16(),QString(tr("时间间隔")).utf16(),5,filePath.utf16())); 2.引用LPRECT时: RECTappRect; ::GetWindowRect(AppWnd,(LP…

在ubunut下使用pycharm和eclipse进行python远程调试

我比较喜欢Pycharm,因为这个是JetBrains公司出的python IDE工具,该公司下的java IDE工具——IDEA,无论从界面还是操作上都甩eclipse几条街,但项目组里有些人使用eclipse比较久了,一时让他们转pycharm比较困难&#xff…

CSS:页脚紧贴底部

2019独角兽企业重金招聘Python工程师标准>>> 我的练习来源于《CSS揭秘》这本书第7章-41紧贴底部的页脚这部分内容以及书中提到的链接。 方案一 描述:以下方案简单、干净、现代并且没有hack,适用于IE8, Chrome, Firefox, Opera等浏览器&#x…

第5章 Python 数字图像处理(DIP) - 图像复原与重建9 - 空间滤波 - 均值滤波器 - 算术平均、几何平均、谐波平均、反谐波平均滤波器

标题只存在噪声的复原 - 空间滤波均值滤波器算术平均滤波器几何均值滤波器谐波平均滤波器反(逆)谐波平均滤波器只存在噪声的复原 - 空间滤波 仅被加性噪声退化 g(x,y)f(x,y)η(x,y)(5.21)g(x, y) f(x, y) \eta(x, y) \tag{5.21}g(x,y)f(x,y)η(x,y)(5…

librosa能量_librosa与python_speech_features

在语音识别领域,比较常用的两个模块就是librosa和python_speech_features了。最近也是在做音乐方向的项目,借此做一下笔记,并记录一些两者的差别。下面是两模块的官方文档LibROSA - librosa 0.6.3 documentation​librosa.github.ioWelcome t…

java Unicode转码

1 //中文转UNICODE2 public static String chinaToUnicode(String str) {3 String result "";4 for (int i 0; i < str.length(); i) {5 int chr1 (char) str.charAt(i);6 if (chr1 > 19968 && ch…

oracle-备份工具exp-imp

虽然是按照用户的方式导出的&#xff0c;但导入之前&#xff0c;还是必须要有相同的用户存在&#xff0c;删除用户以后&#xff0c;是无法进行导入的 --重新创建回zlm用户 SQL> create user zlm identified by zlm; 尽管zlm用户的默认表空间是USERS&#xff0c;但是用imp导入…

继承String?

不能继承&#xff0c;因为 public final class String extends Objectimplements Serializable, Comparable<String>, CharSequence final修饰的类是不能被继承的转载于:https://www.cnblogs.com/crane-practice/p/3666006.html

python中字典数据的特点_Python数据类型(字典)

Python 字典(Dictionary) 字典是另一种可变容器模型&#xff0c;且可存储任意类型对象。 字典的每个键值(key>value)对用冒号(:)分割&#xff0c;每个对之间用逗号(,)分割&#xff0c;整个字典包括在花括号({})中 ,格式如下所示&#xff1a; d {key1: value1, key2: value2}…

第5章 Python 数字图像处理(DIP) - 图像复原与重建10 - 空间滤波 - 统计排序滤波器 - 中值、最大值、最小值、中点、修正阿尔法均值滤波器

标题统计排序滤波器中值、最大值、最小值、中点 滤波器修正阿尔法均值滤波器统计排序滤波器 中值、最大值、最小值、中点 滤波器 f^(x,y)median{g(r,c)}(5.27)\hat{f}(x, y) \text{median} \{g(r,c)\} \tag{5.27}f^​(x,y)median{g(r,c)}(5.27) f^(x,y))max{g(r,c)}(5.28)\ha…

如何设置坐标原点值_氨气检测仪电化学原理及报警值如何设置

氨气体检测仪检定规程&#xff1a;一般氨气体检测仪检定规程主要是针对技术参数设定的一些标准&#xff0c;具体包含有规程的名称和范围、仪器示值误差、充分性标准差、响应时间、稳定性、报警功能、流量控制器、检定项目表、检定操作有数值误差、重复性、响应时间、稳定性等。…

统计信息及相关说明

统计信息&#xff1a;0 recursive calls20434 db block gets 317970511 consistent gets 0 physical reads 3759764 redo size 382 bytes sent via SQL*Net to client 1061 bytes received via SQL*Net from client 3 SQL*Ne…

Android横竖屏切换的生命周期

关于Android手机横竖屏切换时Activity的生命周期问题&#xff0c;网上有很多相似的文章&#xff0c;大多数都是说明在竖屏切换横屏时Activity会重启一次&#xff0c;而在横屏切换竖屏时Activity会重启两次。 我本身不太理解这样设计的意义&#xff0c;并且觉得新版本会解决这个…

python 随机字符串_python生成随机数、随机字符串

python生成随机数、随机字符串 import random import string # 随机整数&#xff1a; print random.randint(1,50) # 随机选取0到100间的偶数&#xff1a; print random.randrange(0, 101, 2) # 随机浮点数&#xff1a; print random.random() print random.uniform(1, 10) # 随…

ACM 会场安排问题

会场安排问题 时间限制&#xff1a;3000 ms | 内存限制&#xff1a;65535 KB难度&#xff1a;4描述学校的小礼堂每天都会有许多活动&#xff0c;有时间这些活动的计划时间会发生冲突&#xff0c;需要选择出一些活动进行举办。小刘的工作就是安排学校小礼堂的活动&#xff0c;…

第5章 Python 数字图像处理(DIP) - 图像复原与重建11 - 空间滤波 - 自适应滤波器 - 自适应局部降噪、自适应中值滤波器

标题自适应滤波器自适应局部降噪滤波器自适应中值滤波器自适应滤波器 自适应局部降噪滤波器 均值是计算平均值的区域上的平均灰度&#xff0c;方差是该区域上的图像对比度 g(x,y)g(x, y)g(x,y)噪声图像在(x,y)(x, y)(x,y)处的值 ση2\sigma_{\eta}^2ση2​ 为噪声的方差&am…

关闭防火墙_从零开始学Linux运维|09.关闭防火墙和SElinux

firewalld是centos7默认的防火墙安全增强型 Linux(Security-Enhanced Linux)简称 SELinux初学者建议先关闭,等熟悉了之后再来使用前期联系中的好多错误都有可能是由于没有关闭或者正确配置上面两项造成的1.临时关闭centos7下的防火墙firewalld一行命令就能够关闭firewalld--&qu…

Discuz!NT - 在线显示列表 游客 bug 修复

引发bug的条件&#xff1a;当你修改了系统组里面的[游客]组 的名字后&#xff01;&#xff01; 你会发现首页上底部的在线显示列表里始终都是显示"游客"字样而非你改过得字样&#xff01;如图 至此你需要运行一个t-sql脚本去修复这个bug&#xff01;&#xff08;但是…