likes
comments
collection
share

一文快速了解 Kotlin 与 Python 的区别学习一门新的语言,最好的方法就是从自己熟悉的语言中找不同。这篇文章就

作者站长头像
站长
· 阅读数 25

学习一门新的语言,最好的方法就是从自己熟悉的语言中找不同。这篇文章就从基本语法、逻辑判断和控制、属性、函数、接口、抽象类、类、集合、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 中没有 switchwhen 关键字。在 python 中,多个条件判断是使用 if-elif-else 关键字。

break、continue

python 的 breakcontinue 的作用和 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 中,逻辑运算符有 andornot,没有 &&||。其中,andor 的功能和 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 通过 privatepublic 等关键字来设置属性的可见性。而在 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 的关键字来简单地实现单例。要实现单例的功能一般有两种方法:

  1. 使用 python 的模块
  2. 类方法

具体可以看 Python中的单例模式的几种实现方式的及优化 - 听风

IO

文件读写

  1. 打开文件: 使用 open() 函数来打开文件。这个函数接受文件名和模式作为参数,并返回一个文件对象。代码示例如下:

    file = open('example.txt', 'r')  # 'r' 表示只读模式
    
    • 常见的文件模式有:
      • 'r':只读模式。
      • 'w':只写模式,如果文件存在则覆盖,不存在则创建。
      • 'a':追加模式,在文件末尾添加内容。
      • 'b':二进制模式,可与其他模式结合使用(如 'rb''wb')。
      • 't':文本模式(默认),可与其他模式结合使用(如 'rt''wt')。
  2. 读取文件

    • 使用文件对象的方法来读取文件内容。代码示例如下:

      content = file.read()  # 读取整个文件内容
      lines = file.readlines()  # 读取所有行并返回一个列表
      for line in file:  # 逐行读取文件
          print(line)
      
  3. 写入文件

    • 打开文件时使用 'w''a' 模式,然后使用文件对象的 write() 方法写入内容。代码示例如下:
      file = open('example.txt', 'w')
      file.write('Hello, world!')
      
  4. 关闭文件

    • 使用 close() 方法关闭文件,以释放资源。

      file.close()
      
    • 也可以使用 with 语句来自动管理文件的打开和关闭。它的作用和 kotlin 的 use 关键字是一样的。代码示例如下:

      with open('example.txt', 'r') as file:
          content = file.read()
      # 当离开 with 代码块时,文件会自动关闭
      
  5. 标准输入输出和错误流

    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 常用的库

  1. NumPy:用于科学计算,提供了高效的多维数组对象和用于处理这些数组的工具。
    • 主要应用场景包括数值计算、线性代数运算、随机数生成等。例如,可以使用 NumPy 进行矩阵运算、快速傅里叶变换等。
  2. Pandas:用于数据处理和分析,提供了数据结构和数据分析工具。
    • 可以方便地处理表格型数据,进行数据清洗、转换、聚合等操作。例如,可以使用 Pandas 读取 CSV 文件、进行数据筛选和排序等。
  3. Matplotlib:用于绘制数据可视化图表。
    • 可以创建各种类型的图表,如折线图、柱状图、散点图等。例如,可以使用 Matplotlib 绘制股票价格走势图、统计图表等。
  4. Scikit-learn:用于机器学习,提供了各种机器学习算法和工具。
    • 可以进行分类、回归、聚类等机器学习任务。例如,可以使用 Scikit-learn 进行图像识别、预测房价等。
  5. TensorFlowPyTorch:深度学习框架。
    • 用于构建和训练深度神经网络。例如,可以使用 TensorFlow 或 PyTorch 进行图像分类、自然语言处理等任务。
  6. Requests:用于发送 HTTP 请求。
    • 可以方便地与 Web 服务进行交互,获取网页内容、提交表单等。例如,可以使用 Requests 爬取网页数据、调用 API 等。
  7. BeautifulSoup:用于解析 HTML 和 XML 文档。
    • 可以从网页中提取特定的信息。例如,可以使用 BeautifulSoup 提取网页中的标题、链接、文本内容等。

参考

转载自:https://juejin.cn/post/7411452970082091045
评论
请登录