初识Python -- 关于类型的困惑

早就听闻过Python的大名,听说python以语法简洁清晰著称于世, 但是一直没有时间系统的学习一下。 我现在做Android应用开发, 对Java还算比较熟悉, 对C和C++也有一定的了解,但是没有学习过Python。现在终于下决心系统的学习一下,写下这篇博客作为学习Python的开端,希望自己能坚持下去。

下面是作为一个python初学者的一些疑惑, 希望能有高人指点迷津


关于在编写Python代码时不指定类型的疑惑


前几天大概熟悉了一下Python的基本语法, 发现和Java有相当大的差别。主要是在编码过程中所有变量没有类型的概念,这让我感觉有点别扭。之前一直写Java代码。在编写Java代码时,每个变量在都有一个类型,并且在编译时都会进行严格的类型检查,如果类型不匹配,直接就会在编译时报错。如下代码所示:

		HashMap map = null;
		ArrayList list = new ArrayList();
		
		map = list;   //error 类型不匹配

而Python在编写的过程中,每个变量都不求写出其类型,如下:

i = 2
print i

说实话,python的这种特性确实让人感觉很别扭, 可能是习惯问题。 这种编辑时无类型的特性,在定义变量和使用变量时还好说,但是在调用别人写好的方法时,我怎样才能知道传递什么样的参数呢? 如下代码:

#define a function with an argument
def print_a_value(value_to_print):
    print value_to_print

#call the function defined above
print_a_value(3)
print_a_value('hello')

如果在方法中只是简单的打印一下传入的参数, 那么传递什么样类型的参数都无所谓,因为所有类型的变量都能被打印,但是如果我在方法内部对传入的参数做一个减操作, 那么再传递字符串类型的参数就不那么合理了:

#define a function with an argument
def print_a_value(value_to_print):
    print value_to_print
    i = value_to_print - 1
    print i

#call the function defined above
print_a_value(3)
print_a_value('hello')

上面这段代码在运行时会报错:

Traceback (most recent call last):
  File "D:\workspace\HelloPython\src\global.py", line 32, in 
    print_a_value('hello')
  File "D:\workspace\HelloPython\src\global.py", line 27, in print_a_value
    i = value_to_print - 1
TypeError: unsupported operand type(s) for -: 'str' and 'int'

报的是类型错误,对减号使用了不支持的操作数。如果print_a_value这个函数不是我写的, 那么我怎么才能知道要传递什么呢?难道只是单纯的靠文档说明吗? 还有如果我是函数的作者, 我在写函数时期望函数的调用者传递一个整形的参数,如果调用者传递了一个错误类型的参数,那么就直接让程序崩溃报错吗? 还是在函数内部像下面这样检查类型? :

#define a function with an argument
def print_a_value(value_to_print):
    if not (type(value_to_print) is types.IntType):
        print 'wrong type'
        return
    
    print value_to_print
    i = value_to_print - 1
    print i

#call the function defined above
print_a_value(3)
print_a_value('hello')

如果这样的话,那么一定会让源代码中充斥着很多检查类型的逻辑, 那么python就不那么简洁了


关于Python是那种类型的语言的疑惑


我在学习javascript时直到有一类语言叫做弱类型语言,而js正好是一种弱类型语言。起初一直对“弱类型语言”这个概念比较模糊,其实现在也不是特别明白,我原来的理解是只要在写代码的时候, 定义的变量不需要指定具体的类型, 那么这种语言就是弱类型的,现在python的出现打破了我的认识,因为python不用指定变量的类型,甚至没有一个js中的像var那样的一个关键字来说明我要声明一个变量,但是通过查阅资料,很多人多认为python是强类型的,这就让人比较迷惑了。 写代码的时候明明没有写类型, 怎么还是强类型呢?

与“强类型语言”, “弱类型语言”类似的一对概念是“静态类型语言”和“动态类型语言”。 把这几个概念进行对比,发现我之前的理解是错误的,我把这几个概念混淆了。经过思考, 我尝试解释一下这几个概念,只是一家之言,若有不对欢迎指正。


静态类型语言:在编写代码时,必须为变量指定一个明确类型的语言。比如Java和C/C++等, 是静态类型的语言。


动态类型语言: 在编写代码时,不必为变量指定一个明确的类型,而是由解释器在运行时根据变量的使用情况确定变量的类型,例如在python中为一个变量i赋值了一个整数0, 那么解释器在解释代码时就将变量i定义成整型。这样的语言一般都是脚本语言,如python,javascript等。下面一个非常简单的示例说明python的动态类型特性:

m = 10;
m = 'hello'
print m     #print 'hello'

在编写代码时是不能定义类型的,但是再解释器解释到m = 10这句代码时,由于给m赋了个整数值,解释器将m定义成整形,然而解释到m = 'hello'这句代码时,由于赋了一个字符串类型的值,那么解释器又将m的类型定义为字符串类型。如果以后不为m赋其他类型的值,那么在程序执行期间m都为字符串类型。

有两点需要注意: 1 动态类型语言也叫动态类型定义语言,关注的焦点是变量的类型是如何被定义的,还有一个概念是“动态性语言”,这个概念是说在运行时动态的改变程序的结构, 比如java的动态加载类, 动态链接类, python在运行期动态改变类的结构等。这两个是不同的概念。2 面向对象的语言如Java和C++等都有一个编译时类型和运行时类型,这是由继承和向上转型引入的,是面向接口(父类编程)和多态的基础, 和这里的 静态类型定义语言, 动态类型定义语言 也不是同一层面的概念。


强类型语言:变量必须有一个确定的类型,不管类型是如何确定的,并且在运行时不能随意的改变变量的类型,也不能将一个类型的变量用作其他不相关的类型。(这里不包括在集成结构上的向上类型转换和向下类型转换,也不包括数值类型之间的转换,如long转int)。比如一个整数不能随意当做字符串来使用。 像Java, C/C++,python等都属于强类型语言。


弱类型语言:在运行时,变量不必按他原来的类型使用,可以当做其他类型来使用,比如可以直接将一个字符串当整数,也可以直接将一个整数当做字符串。javascript就是一种典型的弱类型语言。在网上搜了一个javascript的例子,以说明它的弱类型性:

var result=5+5; //two numbers
alert(result);  //outputs "10"
var result=5+'5'; // a number and a string
alert(result);  //outputs "55"

总结


现在是初学Python,肯定会有所困惑,也会受Java语言的影响,有一些思维定式,一开始难以改变。相信随着学习的不断深入,一些疑惑会逐渐清晰,对Python的理解也会逐渐深入。
虽然在语法特性上Python有很多和Java不同的地方,但是既然Python能如此成功,那么肯定有它自己的语法优势。由于python是纯解释型的脚本语言,这些语法特性肯定和他脚本语言的特性有所联系,也会直接决定解释器的行为。那么随着对python的不断深入,也肯定对这些底层的原理有所了解。


你可能感兴趣的:(Python)