一文快速了解 Kotlin 与 Python 的区别学习一门新的语言,最好的方法就是从自己熟悉的语言中找不同。这篇文章就
学习一门新的语言,最好的方法就是从自己熟悉的语言中找不同。这篇文章就从基本语法、逻辑判断和控制、属性、函数、接口、抽象类、类、集合、IO、泛型、异常、多线程、反射角度看 Kotlin 与 Python 的区别。
基本语法的区别
变量声明
在 python 中,变量不需要显示声明类型,因为变量的类型是动态推断的。代码示例如下:
age = 18
name = "123"
注意:在 python 中没有常量的机制。在 python 中一般使用大写的变量告诉开发者这个变量不应该被修改, 而这个值是否被修改则取决于开发者。
函数的声明
在 python 中使用 def
来声明方法,代码示例如下:
def max(a, b):
if a > b:
return a
else:
return b
需要注意由于 python 是动态语言,因此即使我们声明了参数的类型,使用时设置了其他类型的值也是可以正常运行的。代码示例如下:
def max(a: int, b: int):
if a > b:
return a
else:
return b
max("123", "abc") # a 的类型为 int,但是设置为字符串类型也是没问题的
注释
在 python 中,使用 #
声明单行注释;使用 '''
或者 """
声明多行注释。代码示例如下:
# 单行注释
'''
这是多行注释,使用单引号。
这是多行注释,使用单引号。
这是多行注释,使用单引号。
'''
"""
这是多行注释,使用双引号。
这是多行注释,使用双引号。
这是多行注释,使用双引号。
"""
逻辑判断与控制
if
在 kotlin 中,我们可以使用 if
表达式返回值。但是在 python 中是不可以的,同时在 python 中多个 if-else
被简写成了 elif
。代码示例如下:
if a == 1: # a == 1 可加括号,也可不加
print("a")
else:
print("b")
if a == 1:
print 'a'
elif b == 2: # elif 等同于kotlin中的 else if
print 'b'
elif c == 3:
print 'c'
elif d == 4:
print 'd'
else:
print 'e'
for
python 的 for
和 kotlin 类似,都使用 in
来表明在一定范围内的遍历。代码示例如下:
for letter in 'Python': # 遍历字符串
print(letter)
for num in range(10,20): # 迭代 10 到 20 (不包含) 之间的数字
print(num)
除此之外,python 还支持 for-else
的语法。else
的作用是在循环正常执行完(即 for 不是通过 break 跳出而中断的)时下执行对应的代码。示例如下:
for num in range(1, 3):
for i in range(0, num):
if num > 2:
print(i)
break
else:
print(num)
while
python 的 while
也支持 while-else
的语法,作用是一样的,都是在循环正常执行完时下执行 else 中的代码。至于其他方面,则和 kotlin 的语法是一样的。
when
python 中没有 switch
和 when
关键字。在 python 中,多个条件判断是使用 if-elif-else
关键字。
break、continue
python 的 break
和 continue
的作用和 kotlin 的是一样的。特别的是,python 有一个 pass
关键字,表示占位的作用,类似于 todo
。代码示例如下:
for letter in 'Python':
pass
运算符
算数运算符
在 python 中,大部分的算数运算符和 kotlin 是一样的。因此这里只会列出它们不同的算数运算符,如下面的列表所示:
算数运算符 | 作用 |
---|---|
** | 返回x的y次幂,比如 2**3 就表示 2^3 |
// | 返回商的整数部分(向下取整),比如 9//2 为 4 |
**= | 幂赋值运算符, c **= a 等效于 c = c ** a |
//= | 取整除赋值运算符, c //= a 等效于 c = c // a |
^ | 按位异或运算符,等同于 kotlin 的 xor |
<< | 左移,等同于 kotlin 的 shl |
>> | 右移,等同于 kotlin 的 shr |
逻辑运算符
在 python 中,逻辑运算符有 and
、or
和 not
,没有 &&
和 ||
。其中,and
和 or
的功能和 kotlin 的关键字是一样的,而 not
关键字则等同于 kotlin 中的 !
。
其他
运算符 | 作用 |
---|---|
in | 与 kotlin 中的 in 作用类似,都是表明在一定范围内 |
not in | 等同于 !in |
is | 比较是否是同一个对象,等同于 java 中的 == |
is not | 比较是否是不同的对象 |
kotlin 中的
is
是用于类型检查,确定一个对象是否是特定类型的实例。它的功能等同于 python 中的isinstance
方法。
数据类型
在 Python 中一共有六种标准数据类型,分别是:
- Numbers(数字)
- String(字符串)
- List(列表)
- Set(集合)
- Tuple(元组)
- Dictionary(字典)
数字类型
与 kotlin 不同,python 中的数字类型有三种,分别是:int(整型)、float(浮点型)和 complex(复数)。代码示例如下:
a = 10 # 整型
f = 3.14 # 浮点型
k = 3 + 4j # 复数
# 类型之间的转化
int(f) # 浮点型转化为整形
k.real # 复数的实部
k.imag # 复数的虚部
complex(1.2, 0) # 浮点型转化为复数,1.2 + 0j
字符串类型
在 python 中可以用 ''
(单引号)、 ""
(双引号)、 ''''''
(三引号)来定义字符串。其中三引号定义的字符串中,不需要转义。代码示例如下:
# 三引号定义的字符串
multi_line_str = '''This is a
multi-line string.'''
print(multi_line_str)
在 python 中,我们可以简单地使用 [头下标:尾下标]
来简单地截取对应地字符串。需要注意截取范围是 x >= 头下标 && x < 尾下标
,代码示例如下:
str = 'Hello World!'
print str # 输出完整字符串
print str[0] # 输出字符串中的第一个字符
print str[2:5] # 输出字符串中第三个至第六个之间的字符串
print str[2:] # 输出从第三个字符开始的字符串
print str * 2 # 输出字符串两次
print str + "TEST" # 输出连接的字符串
# 输出地结果如下
Hello World!
H
llo
llo World!
Hello World!Hello World!
Hello World!TEST
列表、Set、元组
在 python 中有列表、元组、Set三种种数据结构。它们的区别如下:
- 列表是可变的,元素可以重复
- 元组是不可变的,元素可以重复
- Set是可变的,元素不可重复的。重复的元素会被去掉。
代码示例如下:
list = [ 'runoob', 786 , 2.23, 'john', 70.2 ] # 等价于 kotlin 的 mutableListOf<Any>()
tuple = ( 'runoob', 786 , 2.23, 'john', 70.2 ) # 等价于 kotlin 的 listOf<Any>()
sites = {'Google', 'Taobao', 'Runoob', 2.23} # 等价于 kotlin 的 setOf<Any>()
和字符串相同,列表和元组都支持[头下标:尾下标]
。区别是列表和元组还可以加一个步长的参数,即 [头下标:尾下标:步长]
字典
python 中字典等价于 kotlin 中的 mutableMapOf<Any>()
,可以存放各种类型的数据。代码示例如下:
tinydict = {'name': 'runoob','code':6734, 'dept': 'sales'}
print dict['one'] # 输出键为'one' 的值
print dict[2] # 输出键为 2 的值
print tinydict # 输出完整的字典
print tinydict.keys() # 输出所有键
print tinydict.values() # 输出所有值
模块和包
在 python 中,一个python文件就是一个模块;一个包含多个模块的目录就是一个包。而在 kotlin 中,一个 kotlin 文件不算做一个模块,一个模块会包含多个 kotlin 文件。
在 python 中,如果你需要使用第三方的模块或者包,需要先通过 pip3 install 模块/包
下载对应的包,然后通过 import
导入。代码示例如下:
pip3 install numpy # 下载 numpy 包
import numpy as np # 导入 numpy 包,并设置它的别名为 np
需要注意: 包中必须包含一个名为
__init__.py
的文件,这个文件可以是空的,但它标志着这个目录是一个 Python 包
集合操作
在 kotlin 中,有很多集合相关的扩展方法。而在 python 中,它也提供了不少内置的方法,这里就介绍一些常用的。代码示例如下:
- list 的常用方法如下:
my_list = [1, 2, 3]
my_list.append(4) # 在列表末尾添加一个元素,等同于 kotlin 的 add
my_list.extend([4, 5]) # 将可迭代对象中的元素添加到列表末尾,等同于 kotlin 的 addAll
my_list.insert(1, 4) # 在指定位置插入一个元素
my_list.remove(2) # 移除列表中第一个值为 2 的元素
popped_item = my_list.pop() # 移除并返回指定位置的元素,默认移除最后一个元素
index = my_list.index(2) # 返回列表中第一个值为 2 的元素的索引
count = my_list.count(2) # 返回列表中值为 2 的元素的个数
my_list.sort() # 对列表进行排序
my_list.reverse() # 反转列表中的元素顺序
len(my_list) # 获取列表的size
my_list.clear() # 清空列表
- set 的常用方法如下:
my_set = {1, 2, 3}
my_set.add(4) # 在set末尾添加一个元素
my_set.update({4, 5}) # 将可迭代对象中的元素添加到set末尾
my_set.remove(2) # 移除set中第一个值为 2 的元素,如果不存在会报错
my_set.discard(2) # 移除set中第一个值为 2 的元素,如果不存在不会报错
popped_item = my_set.pop() # 随机移除set中的元素,如果集合为空则会报错
my_set.union({1, 2}) # 并集
my_set.intersection({1, 2}) # 交集
my_set.issubset({1, 2}) # 判断当前集合是否是另一个集合的子集
len(my_set) # 获取set的size
my_set.clear() # 清空set
- 元组的常用方法如下
my_tuple = (1, 2, 3, 2)
len(my_tuple) # 获取元组的size
index = my_tuple.index(2) # 返回元组中第一个值为 2 的元素的索引
count = my_tuple.count(2) # 返回元组中值为 2 的元素的个数
- 字典的常用方法如下:
my_dict = {'a': 1, 'b': 2, 'c': 3}
len(my_dict) # 获取字典的大小
my_dict.keys() # 返回字典中所有的键
my_dict.values() # 返回字典中所有的值
my_dict.items() # 返回字典中所有的键值对,以可迭代的元组形式
my_dict.get('d', 0) # 返回指定键的值,如果键不存在则返回默认值0
my_dict.setdefault('d', 4) # 如果键存在则返回其对应的值,否则插入键并将值设置为默认值后返回默认值
my_dict.update({'c': 3, 'd': 4}) # 将另一个字典中的键值对添加到当前字典中
my_dict.clear() # 清空字典
类
在 python 中,使用 class
关键字来定义类,创建对象也不需要 new
关键字。除此之外,python 的类与 kotlin 有很大的不同。
属性
首先是在属性上,kotlin 通过 private
、public
等关键字来设置属性的可见性。而在 python 中,私有属性是通过在属性名上加入 __
来实现的。代码示例如下:
class MyClass:
a = 0 # 公开属性
__b = 1 # 私有属性,如果外部访问它会报错
方法
在 python 中的私有方法也是一样,需要在方法名上加入 __
。除此之外,python 类的普通方法必须加上 self
的参数,self
表示当前类的对象;静态方法需要加上 @staticmethod
注解。代码示例如下:
class MyClass:
a = 0 # 公开属性
__b = 1 # 私有属性,如果外部访问它会报错
def f1(self): # 公共方法
print(slef.__b)
def __f2(self): # 私有方法
print(slef.__b)
@staticmethod # 静态方法需要加上 @staticmethod 注解,不需要加上 self
def static_method():
print("This is a static method.")
和 kotlin 一样,python 类也有构造函数,区别是所有 python 类的构造函数都是 __init__
。代码示例如下:
class MyClass:
def __init__(self, a, b): # a 和 b 是自定义的参数
self.a = a
self.b = b
同时 python 也支持操作符重载。代码示例如下:
class MyClass:
def __add__(self,other):
# 这里重载 + 的逻辑
像 __init__
和 __add__
这种方法叫做类的专有方法,所有的类的专有方法如下:
- del : 析构函数,释放对象时使用
- repr : 打印,转换
- setitem : 按照索引赋值
- getitem: 按照索引获取值
- len: 获得长度
- cmp: 比较运算
- call: 函数调用
- add: 加运算
- sub: 减运算
- mul: 乘运算
- truediv: 除运算
- mod: 求余运算
- pow: 乘方
继承
不同于 kotlin 单继承,python 的类可以多继承,它实现继承是使用 ()
。代码示例如下:
class Parent:
def doSomething():
print("parent")
class Child(Parent):
def doSomething(): # 重写父类的方法,不需要关键字
print("child")
枚举
在 python 中,如果需要实现枚举的功能,需要导入 enum
包,才可以使用枚举功能。代码示例如下:
import enum
class Color(enum.Enum):
RED = 1
GREEN = 2
BLUE = 3
def __new__(cls, value, description):
obj = object.__new__(cls)
obj._value_ = value
obj.description = description
return obj
Color.RED = Color(1, "This is red")
Color.GREEN = Color(2, "This is green")
Color.BLUE = Color(3, "This is blue")
单例
python 没有 kotlin 中的 object
的关键字来简单地实现单例。要实现单例的功能一般有两种方法:
- 使用 python 的模块
- 类方法
具体可以看 Python中的单例模式的几种实现方式的及优化 - 听风
IO
文件读写
-
打开文件: 使用
open()
函数来打开文件。这个函数接受文件名和模式作为参数,并返回一个文件对象。代码示例如下:file = open('example.txt', 'r') # 'r' 表示只读模式
- 常见的文件模式有:
'r'
:只读模式。'w'
:只写模式,如果文件存在则覆盖,不存在则创建。'a'
:追加模式,在文件末尾添加内容。'b'
:二进制模式,可与其他模式结合使用(如'rb'
、'wb'
)。't'
:文本模式(默认),可与其他模式结合使用(如'rt'
、'wt'
)。
- 常见的文件模式有:
-
读取文件:
-
使用文件对象的方法来读取文件内容。代码示例如下:
content = file.read() # 读取整个文件内容 lines = file.readlines() # 读取所有行并返回一个列表 for line in file: # 逐行读取文件 print(line)
-
-
写入文件:
- 打开文件时使用
'w'
或'a'
模式,然后使用文件对象的write()
方法写入内容。代码示例如下:file = open('example.txt', 'w') file.write('Hello, world!')
- 打开文件时使用
-
关闭文件:
-
使用
close()
方法关闭文件,以释放资源。file.close()
-
也可以使用
with
语句来自动管理文件的打开和关闭。它的作用和 kotlin 的use
关键字是一样的。代码示例如下:with open('example.txt', 'r') as file: content = file.read() # 当离开 with 代码块时,文件会自动关闭
-
-
标准输入输出和错误流
import sys # 可以使用 `sys.stdin` 来读取用户输入 line = sys.stdin.readline() print(line) # sys.stdout` 用于正常的输出,`sys.stderr` 用于错误输出 sys.stdout.write('This is standard output.') sys.stderr.write('This is an error.')
异常
在 python 中,也有异常的处理,使用的是 try-except-else-finally
的结构。代码示例如下:
try:
run() # 执行操作
except AssertionError as error: # run 发生异常会在调用这里处理异常,等同于 kotlin 中的 catch
print(error)
else: # 如果 run 没有发生异常,执行这里
try:
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
finally: # 等同于 kotlin 中的 finally
print('这句话,无论异常是否发生都会执行。')
如果你需要抛出异常,要使用 raise
关键字。代码示例如下:
class MyException(Exception): # 自定义异常,需要继承 Exception
pass
try:
raise MyException() # 抛出异常
except MyException as e:
print(e.value)
泛型
python 是动态语言,可以任意改变参数的类型。因此,python 是不强制类型匹配的。但是为了提高代码的可读性,以及方便 IDE、语法检查器、类型检查器的检测。python 新增了 typing
模块,可以实现类似的泛型机制,详情可以看 typing —— 对类型提示的支持
线程
在 python 中使用线程需要使用 threading
模块,代码示例如下:
import threading
lock = threading.Lock()
def worker():
lock.acquire() # 加锁
print("I am a thread.")
lock.release() # 释放锁
t = threading.Thread(target = worker)
t.start() # 启动一个线程
协程
在 python 中也支持协程,要在 python 中使用协程需要导入模块 import asyncio
。关于 python 的协程具体可以看 协程与任务
反射
python 支持反射,它内部提供了四个内置函数,通过它们可以在运行时动态地操作对象,使得程序更加灵活和可扩展。
一、hasattr()
用于判断一个对象是否具有某个属性。
class MyClass:
def __init__(self):
self.attr = 42
obj = MyClass()
print(hasattr(obj, 'attr')) # True
print(hasattr(obj, 'nonexistent_attr')) # False
二、getattr()
用于获取对象的属性值。
class MyClass:
def __init__(self):
self.attr = 42
obj = MyClass()
value = getattr(obj, 'attr')
print(value) # 42
如果属性不存在且没有提供默认值,会引发 AttributeError
。
三、setattr()
用于设置对象的属性值。
class MyClass:
def __init__(self):
self.attr = 42
obj = MyClass()
setattr(obj, 'attr', 100)
print(obj.attr) # 100
四、callable()
用于判断一个对象是否可调用(例如函数、方法等)。
def my_function():
return 42
print(callable(my_function)) # True
python 常用的库
- NumPy:用于科学计算,提供了高效的多维数组对象和用于处理这些数组的工具。
- 主要应用场景包括数值计算、线性代数运算、随机数生成等。例如,可以使用 NumPy 进行矩阵运算、快速傅里叶变换等。
- Pandas:用于数据处理和分析,提供了数据结构和数据分析工具。
- 可以方便地处理表格型数据,进行数据清洗、转换、聚合等操作。例如,可以使用 Pandas 读取 CSV 文件、进行数据筛选和排序等。
- Matplotlib:用于绘制数据可视化图表。
- 可以创建各种类型的图表,如折线图、柱状图、散点图等。例如,可以使用 Matplotlib 绘制股票价格走势图、统计图表等。
- Scikit-learn:用于机器学习,提供了各种机器学习算法和工具。
- 可以进行分类、回归、聚类等机器学习任务。例如,可以使用 Scikit-learn 进行图像识别、预测房价等。
- TensorFlow 和 PyTorch:深度学习框架。
- 用于构建和训练深度神经网络。例如,可以使用 TensorFlow 或 PyTorch 进行图像分类、自然语言处理等任务。
- Requests:用于发送 HTTP 请求。
- 可以方便地与 Web 服务进行交互,获取网页内容、提交表单等。例如,可以使用 Requests 爬取网页数据、调用 API 等。
- BeautifulSoup:用于解析 HTML 和 XML 文档。
- 可以从网页中提取特定的信息。例如,可以使用 BeautifulSoup 提取网页中的标题、链接、文本内容等。
参考
转载自:https://juejin.cn/post/7411452970082091045