如何在Python中以C语言风格声明变量类型

75

我是一名编程学生,我的老师开始使用C语言来教授编程范式,他说如果我用Python交作业的话也可以(因为它更容易且速度更快)。我想让我的代码尽可能接近C语言。
问题是:
如何在Python中像C语言一样声明变量的数据类型。例如:

int X,Y,Z;

我知道我可以用Python做到这一点:

x = 0
y = 0
z = 0

但这似乎是很多工作,而且它忽略了 Python 比 C 更容易/更快的重点。 那么,有没有最短的方法来做到这一点?
附言:我知道你大多数时候不用在 Python 中声明数据类型,但我仍然希望这样做,这样我的代码看起来尽可能像同学们的。


4
你似乎没有完全理解Python中的变量。可以将其类比于C语言中的void*指针:它们没有内在类型,是用来引用任何东西的名称。在Python中,对象存在于解释器的内存中,你可以使用变量给它们命名,并记住它们的位置。与C语言不同,Python中的变量没有像C语言那样的类型,它仅仅指向一个对象。 - salezica
8个回答

180

自Python 3.6起,您可以声明变量和函数的类型,例如:

explicit_number: type

或者用于一个函数。
def function(explicit_number: type) -> type:
    pass

这个示例来自《如何在 Python 3.6 中使用静态类型检查》这篇文章,并更加明确易懂。

from typing import Dict
    
def get_first_name(full_name: str) -> str:
    return full_name.split(" ")[0]

fallback_name: Dict[str, str] = {
    "first_name": "UserFirstName",
    "last_name": "UserLastName"
}

raw_name: str = input("Please enter your name: ")
first_name: str = get_first_name(raw_name)

# If the user didn't type anything in, use the fallback name
if not first_name:
    first_name = get_first_name(fallback_name)

print(f"Hi, {first_name}!")

请参阅typing模块的文档。

8
终于有一个恰当的回答来回答这个问题了...但是即使如此,它仍然无法避免将不兼容的值赋给变量。只有像pycharm这样的集成开发环境可以利用这些信息来查找可能的错误... - wmac
2
@wmac 这只是对开发人员的类型提示。确实,智能IDE可以解析它并警告您有关不匹配的信息,但这是它们所能做的最多的事情。 鉴于Python的动态性质,这是可以接受的行为。 - Timor Gruber
谢谢您,这仅供信息/提示目的。 - swdev
例如在Java中,当定义变量类型时,它不允许分配不兼容的类型。但是Python仍然可以这样做。那么它真的有帮助吗? - sjd
如果您需要验证数据对象,可以使用dataclasses https://docs.python.org/3/library/dataclasses.html进行操作,但由于Python的鸭子类型,变量是动态的,可能会发生变异,因此解释器不会检查静态类型,但它有助于文档编写和开发,了解变量的内容。 - Cam T

27

编辑:Python 3.5 引入了类型提示(type hints),这是一种指定变量类型的方法。本回答在此功能推出之前编写。

在 Python 中,没有声明变量的方式,因为既不存在“声明”,也不存在 C 语言意义上的“变量”。以下代码将会把这三个名称绑定到同一个对象:

x = y = z = 0

14
这段内容已过时,Python 3.5支持静态类型。请查看Cam Ts的回答。 - Mandemon

14

简单来说:在Python中打字仅用于提示作用。

x: int = 0
y: int = 0 
z: int = 0

类型提示在VS Code中非常有用,可以方便地访问智能感知功能。 - KalenGi

12

Python并不一定比C更容易/更快,尽管有可能它更简单 ;)

关于你提到的另一种说法"你不需要声明数据类型" - 应该重新表述为你无法声明数据类型。当你将一个值赋给一个变量时,这个值的类型就成为了该变量的类型。这是微妙的不同,但是确实不同。


我认为C语言比Python更简单。它缺少装饰器、元类、描述符等功能。当然,这些都可以在C语言中实现,但那时候你的程序就变得复杂了,而不是底层语言。 - aaronasterling
@aaron - 注意我说的是可能性 :) 我已经用C语言超过25年了,只用Python一年 - 我仍然用C语言编写所有小程序(但不是因为它简单) - KevinDTimm
这种语言在功能方面可能更简单,但关键是实现装饰器、元类、描述符等并不更简单。 - Falmarri
7
C是一种相对简单的语言,但这并不意味着用C编写代码就很简单。 :) - Nate C-K
现在,你可以使用 类型提示 来声明数据类型,但它不会在运行时使用。 - user3064538

11

我很惊讶没有人指出你实际上是可以做到这一点的:

decimalTwenty = float(20)
在许多情况下,输入变量是没有意义的,因为可以随时重新输入。然而在上面的示例中可能会有用。还有其他类似的类型函数,例如:int()long()float()complex()

在许多情况下,键入变量是没有意义的,因为它可以在任何时候重新输入。 然而,在上面的示例中,这可能很有用。 还有其他类似的类型函数,例如:int()long()float()complex()


5
我很惊讶你这样说。因为那不会使你的变量具有类型,这与给变量赋值20.0的效果没有区别... 这两种方法都不能使你的变量永远成为浮点型。你仍然可以将任何值赋给该变量。 - wmac

5

但是强类型和变量定义实际上是为了使开发更容易。如果您没有提前考虑这些问题,那么您不是在设计和开发代码,而只是在进行简单的操作。

松散的类型只是将复杂性从“设计/操作”时间转移到运行时。


4

Python中的一切都是对象,包括类、类实例、函数内的代码、称为模块的函数库以及像整数、浮点数、字符串或容器(如列表和字典)等数据值。甚至包括名称空间,它们是类似于字典的映射容器,用于跟踪标识符名称(字符串对象)与当前存在的对象之间的关联。如果两个或多个标识符与同一个对象相关联,则可以将对象命名为多个名称。

将标识符与对象关联称为“将名称绑定到对象”。这是Python中最接近变量声明的东西。名称可以在不同的时间与不同的对象相关联,因此声明要将哪种类型的数据附加到一个名称是没有意义的——你只需要这样做。通常,在一行或一个代码块中完成,该代码块指定了名称和对象值的定义,从而导致其被创建,例如<variable> = 0或以def <funcname>开头的函数。

这对您有何帮助。


0

我在Python 2和3中使用数据类型来断言唯一值。否则,我无法使它们像str或int类型一样工作。但是,如果您需要检查一个可以具有任何类型的值,除了特定类型之外,那么它们非常有用,并且可以使代码更易读。

继承对象将在Python中创建一个类型。

class unset(object):
    pass
>>> print type(unset)
<type 'type'>
使用示例:您可能希望使用条件或函数处理程序来有条件地过滤或打印一个值,因此使用类型作为默认值将非常有用。
from __future__ import print_function # make python2/3 compatible
class unset(object):
    pass


def some_func(a,b, show_if=unset):
    result = a + b
    
    ## just return it
    if show_if is unset:
        return result
    
    ## handle show_if to conditionally output something
    if hasattr(show_if,'__call__'):
        if show_if(result):
            print( "show_if %s = %s" % ( show_if.__name__ , result ))
    elif show_if:
        print(show_if, " condition met ", result)
        
    return result
    
print("Are > 5)")
for i in range(10):
    result = some_func(i,2, show_if= i>5 )
    
def is_even(val):
    return not val % 2


print("Are even")
for i in range(10):
    result = some_func(i,2, show_if= is_even )

输出

Are > 5)
True  condition met  8
True  condition met  9
True  condition met  10
True  condition met  11
Are even
show_if is_even = 2
show_if is_even = 4
show_if is_even = 6
show_if is_even = 8
show_if is_even = 10

如果show_if=unset是完美使用案例,因为它更安全且易于理解。 我也在枚举中使用过它们,这在Python中并不真实存在。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接