从 JavaScript 角度学 Python(4) - 型别与变数

前言

oh!终於要开始学习写 Python 了呢!(被揍),都混了三天,我如果再不开始写 Python 的话,我想应该一推人准备退订阅了,但是在开始学习之前,我们会先从最基础的型别开始学习,那麽这边也会尽可能使用 JavaScript 两者语法上的差异去做比较与学习唷。

型别

一开始我们先来简单了解一下关於 Python 型别的部分...

https://ithelp.ithome.com.tw/upload/images/20210904/201194861OVtWIkRvF.png

哎,别这样说,虽然我很想再多偷懒个几篇,但是我想是差不多开始认识 Python 怎麽写,但是要开始写之前总要先学基础对吧?

所以在前面我们先快速复习一下 JavaScript 中有哪些原始型别:

  • String - 字串
    • '这是一个字串'
    • "这也是一个字串"
  • Boolean - 布林
    • true
    • false
  • Number - 数字
    • 100000
    • 3.141592653
  • Undefined - 未定义
  • Null - 空值

以及後来新增的:

  • Bigint - 整数数值
    • 9007199254740991n
  • Symbol - Symbol

这些之外的我们通通称之为物件型别,所以通常会看到人家讲原始型别与物件型别。

如果你对於 JavaScript 的型别观念还不是那麽熟悉的话,那麽我建议你可以阅读我先前写的「JavaScript 核心观念(14)-运算子、型别与文法-原始型别及物件型别」文章会有更详细的说明唷!

那麽 Python 呢?Python 的型别主要区分为三大类:

  • 数值型别
  • 字串型别
  • 容器型别

很特别吧?竟然直接区分成三种型别,尤其是容器型别更是特别。

一开始我们先来聊聊比较接近 JavaScript 型别的「数值型别」与「字串型别」,而容器型别我们在别的章节再来聊吧!

不可否认 Python 与 JavaScript 在型别定义上确实是比较不一样,所以就让我们先来看看「数值型别」与「字串型别」,虽然是讲数值型别与字串型别,但是实际上这两个型别底下还会再细分相关的型别:

  • 数值型别
    • int - 整数
    • floats - 浮点数
    • boolean - 布林
  • 字串型别
    • string - 就是字串你还想怎样?

https://ithelp.ithome.com.tw/upload/images/20210904/20119486eDqhhNb8GI.jpg

(前面开玩笑的。)

字串型别与 JavaScript String 型别并没有任何差异,但是我们可以看到最明显的差异是在於「数值型别」,在 JavaScript 中不论是 var num = 1.23456; 或者是 var num2 = 123;,我们都是通通归类为 Number 型别,当然我们也可以验证一下:

var num = 1.23456;
var num2 = 123;
console.log('Number', typeof(num)); // Number number
console.log('Number', typeof(num2)); // Number number

只是在 Python 中却有区分出 int 型别与 floats 型别,这两者型别如何辨识呢?只需要看它有没有小数点就对了。

若有小数点的话就是浮点数,所以 var num = 1.23456; 在 Python 中其实是浮点数(floats),而 var num2 = 123; 则是整数(int)。

那...JavaScript 中的 UndefinedNull 呢?Python 也存在吗?

Undefined 就不说了,毕竟这是 JavaScript 的特殊型别,只要你有在变数宣告之前呼叫过变数的话,一定很常看到 Undefined (这部分又牵扯到提升就不提了。):

console.log(myName); // undefined
var myName = 'Ray';

但是 Null 这个型别也不存在於 Python 中,所以如果你若输入以下语法是会出现错误的,那这边我们就来简单写一点点的 Python 来验证看看:

(注意,Python 不用加上结尾分号)

hello = Null # name 'Null' is not defined

取而代之的是 Python 所使用的是 None,这边要注意 None 显示出来会是一个 Nonetype:

hello = None
type(hello) # <class 'NoneType'>

(type 的语法与 JavaScript 的 typeof 相同,主要是查看型别用。)

所以可以把 JavaScript 的 Null 想像成是 Python 的 None

除此之外 <class 'NoneType'> 这一段的意思是在讲这个变数是 NoneType 类型,如果是一个字串的话,就会是 <class 'str'> 也就是字串类型概念,而 None 这也是属於 Python 的特殊型别。

题外话一下在 Python 2.x 则是显示 <type 'str'>,只是在 Python 3.x 改成了 <class 'str'> 而已,所以不论是 <class 'str'> 还是 <type 'str'> 都是代表着当前变数是什麽型别的意思。

变数

变数可以说是所有程序语言最基础最重要的起手式,因为我们会很常需要使用变数储存资料,如果以 JavaScript 作为举例就是储存 AJAX 回来的资料最为常见。

这边以 JavaScript 作为起手式,当我们在建立变数时,通常都会使用 var 或者 ES6 语法 letconst,以下这边就先以 var 作为举例:

var myNameTest = 'Ray';
var numTest = 1;
var num2Test = 3.14
var boolTest = true;

console.log('String', typeof(myNameTest)); // String string
console.log('Number', typeof(numTest)); // Number number
console.log('Number', typeof(num2Test)); // Number number
console.log('Boolean', typeof(boolTest)); // Boolean boolean

Python 在宣告变数上与 JavaScript 是有一点点的不同,在 Python 中我们可以不使用任何的变数宣告关键字 (varlet or const) 来宣告变数,只需要直接撰写变数名称并赋予值或结果就可以了。

底下这边就以上方示范的 JavaScript 范例直接改写成 Python 结构:

myNameTest = 'Ray'
numTest = 1
num2Test = 3.14
boolTest = True

这边你应该会注意到 Python 的 Boolean 是采用首字大写的方式撰写,这个与 JavaScript Boolean 全小写完全不同,这是一个小细节要注意一下:

boolTest = True
boolTest = False

通常我们在撰写 JavaScript 的时候,我们可以使用 console.log 输出结果,而 Python 则是使用 print() 函式输出结果:

myNameTest = 'Ray'
numTest = 1
num2Test = 3.14
boolTest = True

print('String', type(myNameTest))
print('Number', type(numTest))
print('Float', type(num2Test))
print('Boolean', type(boolTest))

(题外话一下 console.xxx 还有很多种,例如:console.dirconsole.table 等等,如果你不熟悉的话,可以阅读我这一篇笔记 「浅谈 JavaScript 中的 Debug 神器 Console」 了解一下。)

最後让我们稍微透过一张图一起比较一下两者语法差异:

https://ithelp.ithome.com.tw/upload/images/20210904/201194860W2NbstLnn.png

将两种程序语言放在一起之後应该会有人觉得 Python 的语法确实简洁相当多,可能会萌生我该学 JavaScript 还是 Python 的错觉,那我就会这样给你一张图:

https://ithelp.ithome.com.tw/upload/images/20210904/20119486E8C10vP6kX.png

重新赋值

接下来我们来聊聊 重新赋值 这个行为,在 JavaScript 中会依据你的宣告方式的不同,而决定你这个变数是否可以被 再次重新赋值,因此让我们看一下 JavaScript 宣告范例:

var myName = 'Ray';
myName = 'Ray'; // 可以被重新赋值
let sayHi = 'Hello Ray';
sayHi = 'Ray Hello'; // 可以被重新赋值
const isRay = 'not Array';
isRay = 'is Array'; // 无法被重新赋值

var 与 ES6 语法又有些许不同,因此这边不着墨在 JavaScript 宣告变数上,若想再深入了解可以阅读我先前写「浅谈 var 与 let 的差异以及有无宣告变数的差异」这一篇。

回到宣告变数的部分,使用 let 宣告的变数,若再一次使用 let 关键字重新宣告变数,是会出现错误的:

let myName;
let myName; // Uncaught SyntaxError: redeclaration of let myName

除此之外 JavaScript 的变数宣告又会因为宣告方式的不同而有作用域以及提升的问题,已经头晕了吗?不用担心,这边不会继续着墨 JavaScript 的部分。

那麽 Python 呢?Python 会有这个问题吗?

https://ithelp.ithome.com.tw/upload/images/20210904/20119486aKEFKeNgex.jpg

接下来的观念可能会与你在学 JavaScript 的观念有一点冲突,主要原因是出在我们前面有讲过 Python 在宣告变数时,是不用使用关键字来宣告的,因此就算你这样子写,也不会出现错误:

myNameTest = 'Ray'
print(myNameTest) # 'Ray'
myNameTest = 123
print(myNameTest) # 123

为什麽会这样呢?对於 Python 来讲 你并没有重新宣告变数,而是告诉变数重新指向到新的值而已,这也就是为什麽并不会出现错误的原因,所以你也可以把它想像成 Python 是使用了 let 作为宣告,为什麽这样说呢?因为如果你在变数宣告之前就先呼叫了这个变数是会出现错误的:

print(myNameTest) # NameError: name 'myNameTest' is not defined
myNameTest = 'Ray'
print(myNameTest)
myNameTest = 123
print(myNameTest)

概念是不是很很像 letconst 的暂时性死区概念呢(若不清楚暂时性死区可详见 此篇 笔记)?这就是为什麽我会说可以把它想像成 let 了。那你可能会问说 Python 会有 Hoisting 吗?我想是没有的。

毕竟提升 (Hoisting) 这个行为是 JavaScript 独特的运作模式。

最後是关於作用域的部分,关於作用域我打算下一次再来分享,看到现在的你有没有感觉到 JavaScript 与 Python 各自美好之处呢?

https://ithelp.ithome.com.tw/upload/images/20210904/20119486F8J9OOA45B.png

执行 Python

接下来相信会有人疑惑该如何输入上面这些程序码,基本上有两种方式

第一种是打开终端机,然後输入 python 就会进入 Python 编译器,概念就跟我们在终端机输入 node 一样:

https://ithelp.ithome.com.tw/upload/images/20210904/20119486mUjci7xw0E.png

(上图出现 Python 2.7 可忽略)

这边退出终端机模式可以输入 exit()quit() 等指令退出,或者是依据作业系统的组合按钮来退出 Python 模式:

  • Window
    • CTRL + D
  • Mac
    • Control + D

第二种方式则是透过编辑器,这边我是使用 VSCode 建立一个档案叫做 ch1.py,然後贴入下方内容:

# 字串 string
myName = 'Ray'
blogUrl = 'https://hsiangfeng.github.io/'
# 输出
print('字串 string', myName) # 字串 string Ray
print('字串 string', blogUrl) # 字串 string https://hsiangfeng.github.io/

接下来透过 VSCode 直接执行 .py 就可以看到结果罗

https://ithelp.ithome.com.tw/upload/images/20210904/20119486A72T3DEeia.png

作者的话

因为自己满喜欢吃台酒的花雕鸡泡面,所以异想天开的买了维力鸡汁风味手打面以及一罐花雕鸡酒,没想到维力鸡汁风味手打面和花雕鸡酒加在一起後异常的香跟好吃,重点是花雕香可以自己决定。

关於兔兔们

兔法无边


<<:  组织可以在稽核的时侯,向供应商索取 ISMS 相关文件吗?

>>:  电子书阅读器上的浏览器 [Day05] 提高图案对比度

14.移转 Aras PLM大小事-开发报表 Where Used Top Level Product

本篇放上获得最上阶产品料号的作法 1.建立报表 2.设定SQL语法 3.设定Method 4.设定X...

Day20 ( 中级 ) 依序点灯 ( 座标 )

依序点灯 ( 座标 ) 教学原文参考:依序点灯 ( 座标 ) 这篇文章会介绍如何使用「点亮」、「计次...

Learning How to Make a Movie

"The Great Movie Experience" as Myron En...

其他名词解释 | ML#Day23

承上一篇,模型训练完成之後的那些Vertex列出评估函数,除了R^2也一并介绍剩下的名词。 MAE ...

【PHP Telegram Bot】Day19 - 基础(8):回圈、Xdebug

当需要重复做类似的事情时,不需要写很多行重复的程序,用回圈就能一次执行很多次 回圈 while 如...