Python과 Javascript 비교

高洛峰
풀어 주다: 2016-10-18 09:42:47
원래의
1003명이 탐색했습니다.

최근에는 업무상의 필요로 인해 Python 관련 개발을 시작했습니다. 이전에 Javascript를 사용해 왔기 때문에 무의식적으로 Javascript 개념, 구문 등을 사용하여 함정에 빠질 때가 많습니다. Javascript에서 Python으로 전환할 때 차이점을 정리할 필요가 있다고 생각합니다.

기본 개념

Python과 Javascript는 모두 스크립팅 언어이므로 많은 공통 기능을 가지고 있으며 둘 다 실행하려면 인터프리터가 필요하고 둘 다 동적 유형이며 둘 다 자동 메모리 관리를 지원합니다. 확인 eval()을 호출하여 스크립트 언어에 일반적인 스크립트 및 기타 기능을 실행합니다.

그러나 Javascript는 원래 클라이언트 측 스크립팅 언어로 설계되었으며 주로 브라우저에서 사용되는 반면 Python은 "우아함"으로 인해 C를 기반으로 합니다. "명확하고" "단순한" 디자인으로 인기가 높으며 교육, 과학 컴퓨팅, 웹 개발 등 다양한 시나리오에서 사용됩니다.

프로그래밍 패러다임

Python과 Javascript는 모두 다양한 프로그래밍 패러다임을 지원하며 객체 지향 프로그래밍에서는 매우 다릅니다. Javascript의 객체 지향 접근 방식은 프로토타입(객체)에서 생성됩니다. 프로토타입 객체에서 생성된 객체는 프로토타입 체인의 메서드를 상속합니다. 반면에 Python은 클래스(클래스) 상속을 기반으로 하는 상당히 표준적이며 자연스럽게 다형성(polymorphine)을 지원합니다.

Pyhton의 OO

class Employee:
   'Common base class for all employees'
   empCount = 0 ##类成员
  
   def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
     
   def displayCount(self):
     print "Total Employee %d" % Employee.empCount
  
   def displayEmployee(self):
      print "Name : ", self.name,  ", Salary: ", self.salary
## 创建实例
ea = Employee("a",1000)
eb = Employee("b",2000)
OO in Javascript
var empCount = 0;
//构造函数
function Employee(name, salary){
    this.name = name;
    this.salary = salary;   
    this.empCount += 1;
}
  
Employee.prototype.displayCount = function(){
    console.log("Total Employee " + empCount );
}
  
Employee.prototype.displayEmployee = function(){
    console.log("Name " + this.name + ", Salary " + this.salary );
}
//创建实例
var ea = new Employee("a",1000);
var eb = new Employee("b",2000);
로그인 후 복사

객체 상속을 기반으로 하기 때문에 Javascript에서는 클래스 멤버를 사용할 방법이 없습니다. empCount이므로 전역 변수가 선언되어야 합니다. 물론 실제 개발에서는 보다 적절한 범위를 사용하게 됩니다. Javascript에서는 객체를 생성하려면 new 키워드가 필요하지만 Python에서는 그렇지 않습니다.

네이티브 프로토타입 기반 상속 외에도 클래스 상속을 시뮬레이션하기 위해 클로저나 프로토타입을 사용하는 Javascript OO 도구가 많이 있으므로 이에 대해서는 논의하지 않습니다.

스레딩 모델

JavaScript에는 멀티스레딩이라는 개념이 없습니다. 모든 JavaScript 프로그램은 하나의 스레드에서 실행됩니다. HTML5의 웹 워커 도입으로 작업을 동시에 처리할 수 있지만 Javascript의 단일 스레드 제한은 변경되지 않습니다.

Python은 스레드 패키지를 통해 멀티스레딩을 지원합니다.

불변 유형

Python에서 일부 데이터 유형은 불변입니다. 즉, 이러한 유형의 데이터는 수정할 수 없으며 모든 수정 사항은 새 객체로 반환됩니다. Javascript의 모든 데이터 유형은 변경될 수 있습니다. Python에서는 스레드 안전성을 지원하기 위해 불변 유형을 도입했다고 생각하며, Javascript는 단일 스레드 모델이므로 불변 유형을 도입할 필요가 없습니다.

물론 Javascript에서는 객체의 속성을 읽기 전용으로 정의할 수 있습니다.

var obj = {};Object.defineProperty(obj, "prop", {
    value: "test",
    writable: false});
로그인 후 복사

ECMAScript5 지원을 통해 Object의 동결 메소드를 호출하여 객체를 수정할 수 없게 만들 수도 있습니다.

Object.freeze(obj)

데이터 유형

Javascript 데이터 유형은 객체, 문자열, 부울, 숫자, null 및 정의되지 않음을 포함하여 비교적 간단하며 총 6개입니다. 유형

파이썬에서는 모듈, 함수, 클래스 등 모든 것이 객체입니다.

Python에는 bool, int, long, float 및 complex 5가지 단순 데이터 유형과 컨테이너 유형, 코드 유형, 내부 유형 등이 내장되어 있습니다.

부울

자바스크립트에는 참과 거짓이 있습니다. 파이썬에는 True와 False가 있습니다. 대문자를 제외하고는 차이점이 없습니다.

문자열

Javascript는 UTF16 인코딩을 사용합니다.

파이썬은 ASCII 코드를 사용합니다. 인코딩 변환을 수행하려면 encode 및 decode를 호출해야 합니다. 문자열이 유니코드 인코딩을 사용하도록 지정하려면 접두사로 u를 사용합니다.

숫자 값

Javascript의 모든 숫자 유형은 64비트 부동 소수점 숫자로 구현됩니다. NaN(숫자 아님), 플러스 또는 마이너스 무한대(+/-무한대)를 지원합니다.

파이썬에는 숫자형이 많은데 그 중 복수형이 매우 편리해서 과학 연구나 교육 분야에서 파이썬이 인기가 많습니다. 이것이 이유 중 하나일 것입니다. NaN은 Python에 정의되어 있지 않으며 0으로 나누기 작업은 예외를 발생시킵니다. <… 이해할 수 있는 것은 불변의 목록입니다.

Python에서 길이를 구하기 위해 내장된 len 메소드를 사용하는 것 외에도 기본적으로 Javascript와 Python 모두 목록을 조작하는 유사한 메소드를 제공합니다. Python의 목록 첨자 작업은 매우 유연하고 편리합니다. 이는 Javascript에는 없는 기능입니다. 예를 들어 l[5:-1], l[:6] 등입니다.

사전, 해시 테이블, 객체

Javascript는 객체를 생성하기 위해 {}를 광범위하게 사용합니다. 이러한 객체는 객체의 멤버에 액세스하기 위해 [] 또는 를 사용할 수 있습니다. 구성원은 동적으로 추가, 수정 및 삭제할 수 있습니다. 객체를 자바스크립트 사전이나 해시 테이블로 생각할 수 있습니다. 객체의 키는 문자열이어야 합니다.

Python에는 해시 테이블(dictS)이 내장되어 있습니다. Javascript와 달리 dictS에는 다양한 유형의 키 값이 있을 수 있습니다.

Null 값

Javascript는 두 가지 유형의 Null 값을 정의합니다. 정의되지 않음은 변수가 초기화되지 않았음을 의미하고, null은 변수가 초기화되었지만 값이 비어 있음을 의미합니다.

Python中不存在未初始化的值,如果一个变量值为空,Python使用None来表示。

Javascript中变量的声明和初始化

v1;
v2 = null;
var v3;
var v4 = null;
var v5 = &#39;something&#39;;
로그인 후 복사

在如上的代码中v1是全局变量,未初始化,值为undefined;v2是全局变量,初始化为空值;v3为局部未初始化变量,v4是局部初始化为空值的变量;v5是局部已初始化为一个字符处的变量。

Python中变量的声明和初始化

v1 = None

v2 = 'someting'

Python中的变量声明和初始化就简单了许多。当在Python中访问一个不存在的变量时,会抛出NameError的异常。当访问对象或者字典的值不存在的时候,会抛出AttributeError或者KeyError。因此判断一个值是否存在在Javascript和Python中需要不一样的方式。

Javascript中检查某变量的存在性:

if (!v ) {
    // do something if v does not exist or is null or is false
}
  
if (v === undefined) {
    // do something if v does not initialized
}
로그인 후 복사

注意使用!v来检查v是否初始化是有歧义的因为有许多种情况!v都会返回true

Python中检查某变量的存在性:

try:
    v
except NameError
    ## do something if v does not exist
로그인 후 복사

在Python中也可以通过检查变量是不是存在于局部locals()或者全局globals()来判断是否存在该变量。

类型检查

Javascript可以通过typeof来获得某个变量的类型:

typeof in Javascript 的例子:

typeof 3 // "number"
typeof "abc" // "string"
typeof {} // "object"
typeof true // "boolean"
typeof undefined // "undefined"
typeof function(){} // "function"
typeof [] // "object"
typeof null // "object"
로그인 후 복사

要非常小心的使用typeof,从上面的例子你可以看到,typeof null居然是object。因为javscript的弱类型特性,想要获得更实际的类型,还需要结合使用instanceof,constructor等概念。具体请参考这篇文章

Python提供内置方法type来获得数据的类型。

>>> type([]) is list
True
>>> type({}) is dict
True
>>> type(&#39;&#39;) is str
True
>>> type(0) is int
True
로그인 후 복사

同时也可以通过isinstance()来判断类的类型

class A:
    pass
class B(A):
    pass
isinstance(A(), A)  # returns True
type(A()) == A      # returns True
isinstance(B(), A)    # returns True
type(B()) == A        # returns False
로그인 후 복사

但是注意Python的class style发生过一次变化,不是每个版本的Python运行上述代码的行为都一样,在old style中,所有的实例的type都是‘instance’,所以用type方法来检查也不是一个好的方法。这一点和Javascript很类似。

自动类型转换

当操作不同类型一起进行运算的时候,Javascript总是尽可能的进行自动的类型转换,这很方便,当然也很容易出错。尤其是在进行数值和字符串操作的时候,一不小心就会出错。我以前经常会计算SVG中的各种数值属性,诸如x,y坐标之类的,当你一不小心把一个字符串加到数值上的时候,Javascript会自动转换出一个数值,往往是NaN,这样SVG就完全画不出来啦,因为自动转化是合法的,找到出错的地方也非常困难。

Python在这一点上就非常的谨慎,一般不会在不同的类型之间做自动的转换。

语法

风格

Python使用缩进来决定逻辑行的结束非常具有创造性,这也许是Python最独特的属性了,当然也有人对此颇具微词,尤其是需要修改重构代码的时候,修改缩进往往会引起不小的麻烦。

Javascript虽然名字里有Java,它的风格也有那么一点像Java,可是它和Java就好比雷峰塔和雷锋一样,真的没有半毛钱的关系。到时语法上和C比较类似。这里必须要提到的是coffeescript作为构建与Javascript之上的一种语言,采用了类似Python的语法风格,也是用缩进来决定逻辑行。

Python风格

def func(list):
    for i in range(0,len(list)):
        print list[i]
Javascript风格
function funcs(list) {
    for(var i=0, len = list.length(); i < len; i++) {
        console.log(list[i]);
    }
}
로그인 후 복사

从以上的两个代码的例子可以看出,Python确实非常简洁。

作用范围和包管理

Javascript的作用域是由方法function来定义的,也就是说同一个方法内部拥有相同的作用域。这个严重区别与C语言使用{}来定义的作用域。Closure是Javascript最有用的一个特性。

Python的作用域是由module,function,class来定义的。

Python的import可以很好的管理依赖和作用域,而Javascript没有原生的包管理机制,需要借助AMD来异步的加载依赖的js文件,requirejs是一个常用的工具。

赋值逻辑操作符

Javascript使用=赋值,拥有判断相等(==)和全等(===)两种相等的判断。其它的逻辑运算符有&& 和||,和C语言类似。

Python中没有全等,或和与使用的时and 和 or,更接近自然语言。Python中没有三元运算符 A :B ?C,通常的写法是

(A and B) or C

因为这样写有一定的缺陷,也可以写作

B if A else C

Python对赋值操作的一个重要的改进是不允许赋值操作返回赋值的结果,这样做的好处是避免出现在应该使用相等判断的时候错误的使用了赋值操作。因为这两个操作符实在太像了,而且从自然语言上来说它们也没有区别。

++运算符

Python不支持++运算符,没错你再也不需要根据++符号在变量的左右位置来思考到底是先加一再赋值呢还是先赋值再加一。

连续赋值

利用元组(tuple),Python可以一次性的给多个变量赋值

(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7)

函数参数

Python的函数参数支持命名参数和可选参数(提供默认值),使用起来很方便,Javascript不支持可选参数和默认值(可以通过对arguments的解析来支持)

def info(object, spacing=10, collapse=1):

... ...

其它

立即调用函数表达式 (IIFE)

Javascript的一个方便的特性是可以立即调用一个刚刚声明的匿名函数。也有人称之为自调用匿名函数。

下面的代码是一个module模式的例子,使用闭包来保存状态实现良好的封装。这样的代码可以用在无需重用的场合。

var counter = (function(){
    var i = 0;
    return {
        get: function(){
            return i;
            },
        set: function( val ){
            i = val;
            },
        increment: function() {
            return ++i;
            }
        };
    }());
로그인 후 복사

Python没有相应的支持。

生成器和迭代器(Generators & Iterator)

在我接触到的Python代码中,大量的使用这样的生成器的模式。

Python生成器的例子

# a generator that yields items instead of returning a list
def firstn(n):
    num = 0
    while num < n:
        yield num
        num += 1
    
sum_of_first_n = sum(firstn(1000000))
로그인 후 복사

Javascript1.7中引入了一些列的新特性,其中就包括生成器和迭代器。然而大部分的浏览器除了Mozilla(Mozilla基本上是在自己玩,下一代的Javascript标准应该是ECMAScript5)都不支持这些特性

Javascript1.7 迭代器和生成器的例子。

function fib() {
  var i = 0, j = 1;
  while (true) {
    yield i;
    var t = i;
    i = j;
    j += t;
  }
};
  
var g = fib();
for (var i = 0; i < 10; i++) {
  console.log(g.next());
}
로그인 후 복사

列表(字典、集合)映射表达式 (List、Dict、Set Comprehension)

Python的映射表达式可以非常方便的帮助用户构造列表、字典、集合等内置数据类型。

下面是列表映射表达式使用的例子:

>>> [x + 3 for x in range(4)]
[3, 4, 5, 6]
>>> {x + 3 for x in range(4)}
{3, 4, 5, 6}
>>> {x: x + 3 for x in range(4)}
{0: 3, 1: 4, 2: 5, 3: 6}
로그인 후 복사

Javascript1.7开始也引入了Array Comprehension

var numbers = [1, 2, 3, 4];
var doubled = [i * 2 for (i of numbers)];
로그인 후 복사

Lamda表达式 (Lamda Expression )

Lamda表达式是一种匿名函数,基于著名的λ演算。许多语言诸如C#,Java都提供了对lamda的支持。Pyhton就是其中之一。Javascript没有提供原生的Lamda支持。但是有第三方的Lamda包。

g = lambda x : x*3

装饰器(Decorators)

Decorator是一种设计模式,大部分语言都可以支持这样的模式,Python提供了原生的对该模式的支持,算是一种对程序员的便利把。

Decorator的用法如下。

@classmethod
def foo (arg1, arg2):
    ....
로그인 후 복사


   


관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!