MySQL的重要語法

MySQL的重要語法

[帳號與權限] [資料庫/資料表/欄位的操作] [紀 錄的操作] [資料的 輸出]

一、帳號與權限

設定 root 和其他 user 的密碼

  • mysqladmin -u root password '新密碼'
  • mysqladmin -u root -p
  • Enter password:    此時再輸入密碼(建議採用)
  • use mysql;
    mysql> UPDATE user SET password=password('新密碼') where user='root'; 
      只改 root 的密碼,如果沒有用 where ,則表示改全部 user 的密碼
  • mysql> FLUSH PRIVILEGES; 在 mysql 資料庫內,一定要用 flush 更新記憶體上的資料

刪除空帳號

  • mysql> DELETE FROM user WHERE User = '';
  • mysql> FLUSH PRIVILEGES;
     

建立新帳號

  • mysql> GRANT 權限 ON 資料庫或資料表 TO 使用者 IDENTIFIED BY '密碼';
      權限
       
      資料庫或資料表
       *.* 所有資料庫裡的所有資料表
       * 預設資料庫裡的所有資料表
       資料庫.* 某一資料庫裡的所有資料表   
       資料庫.資料表 某一資料庫裡的特定資料表
       資料表  預設資料庫裡的某一資料表

設定/修改權限  

  • 用 root 登入 MySQL
     
    mysqladmin -u root -p
     Enter password:   
  • mysql> GRANT all ON db35.* TO s35@'localhost' IDENTIFIED BY 's35';
       把 db35 這個資料庫(含其下的所有資料表),授權給 s35,從 localhost 上來,密碼為s35
     
  • mysql> GRANT all ON *.*  把所有資料庫及資料表授權給別人,太危險了!
     
  • mysql> GRANT all??? ON www.* TO '*'@'*' IDENTIFIED BY '';
       
    把 www 這個資料庫(含其下的所有資料表),授權給 任何機器任何人,無密碼(通常給不特定人士使用)
     
  • mysql> FLUSH PRIVILEGES; (最後一定要強迫更新權限)

 

二、資料庫/資料表/欄位的操作

建立資料庫 CREATE DATABASE 資料庫名;
語法:CREATE DATABASE db_name

使用資料庫 USE 資料庫名;
語法:USE db_name

刪除資料庫 DROP DATABASE 資料庫名;
語法:DROP DATABASE [IF EXISTS] db_name
 
建立資料表
 CREATE TABLE 資料表名 (欄位1 資料型態, 欄位2 資料型態, ......);
語法:
CREATE TABLE [IF NOT EXISTS] tbl_name (create_definition,...) [table_options] [select_statement]

例:
craete database basic;
use basic;
create table basic(
  no char(4)
  name char(10)
  id char(10));

create_definition:
col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT]
[PRIMARY KEY] [reference_definition]
or PRIMARY KEY (index_col_name,...)
or KEY [index_name] KEY(index_col_name,...)
or INDEX [index_name] (index_col_name,...)
or UNIQUE [INDEX] [index_name] (index_col_name,...)
or [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...)
[reference_definition]
or CHECK (expr)

資料結構(type):

資料型態 說明
TINYINT 有符號的範圍是-128127, 無符號的範圍是0255
SMALLINT 有符號的範圍是-3276832767, 無符號的範圍是065535
MEDIUMINT 有符號的範圍是-83886088388607, 無符號的範圍是016777215
INT 有符號的範圍是-21474836482147483647, 無符號的範圍是04294967295
INTEGER INT的同義詞。
BIGINT 有符號的範圍是-9223372036854775808到 9223372036854775807,無符號的範圍是0到18446744073709551615。
FLOAT 單精密浮點數字。不能無符號。允許的值是-3.402823466E+38到- 1.175494351E-38,0 和1.175494351E-38到3.402823466E+38。
DOUBLE 雙精密)浮點數字。不能無符號。允許的值是- 1.7976931348623157E+308到-2.2250738585072014E-308、 0和2.2250738585072014E-308到1.7976931348623157E+308。
DOUBLE PRECISION DOUBLE的同義詞。
REAL DOUBLE的同義詞。
DECIMAL DECIMAL值的最大範圍與DOUBLE相 同。
NUMERIC DECIMAL的同義詞。
DATE 日期。支援的範圍是'1000-01-01'到'9999-12-31'。
DATETIME 日期和時間組合。支援的範圍是'1000-01-01 00:00:00''9999-12-31 23:59:59'
TIMESTAMP 時間戳記。範圍是'1970-01-01 00:00:00'到2037年的某時。
TIME 一個時間。範圍是'-838:59:59''838:59:59'
YEAR 2或4位數字格式的年(內定是4位)。允許的值是1901到2155。
CHAR 固定長度,1 ~ 255個字元。
VARCHAR 可變長度,1 ~ 255個字元。
TINYBLOB

TINYTEXT 最大長度為255(2^8-1)個字符。
MEDIUMBLOB

MEDIUMTEXT 最大長度為16777215(2^24-1)個字符。
LONGBLOB

LONGTEXT 最大長度為4294967295(2^32-1)個字符。
ENUM 一個ENUM最多能有65535不同的值。
SET 一個SET最多能有64個成員。


index_col_name:
col_name [(length)]

reference_definition:
REFERENCES tbl_name [(index_col_name,...)]
[MATCH FULL | MATCH PARTIAL]
[ON DELETE reference_option]
[ON UPDATE reference_option]

reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

table_options:
type = [ISAM | MYISAM | HEAP]
or max_rows = #
or min_rows = #
or avg_row_length = #
or comment = "string"
or auto_increment = #
select_statement:
[ | IGNORE | REPLACE] SELECT ... (Some legal select statement)

刪除資料表 DROP TABLE 資料表名;
語法:DROP TABLE [IF EXISTS] tbl_name [, tbl_name,...]

改變資料表結構(新增/刪除欄位、建立/取消索引、改變欄位資料型態、欄位重新命 名)
語法:
ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...]

alter_specification:
ADD [COLUMN] create_definition [FIRST | AFTER column_name ]
or ADD INDEX [index_name] (index_col_name,...)
or ADD PRIMARY KEY (index_col_name,...)
or ADD UNIQUE [index_name] (index_col_name,...)
or ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
or CHANGE [COLUMN] old_col_name create_definition
or MODIFY [COLUMN] create_definition
or DROP [COLUMN] col_name
or DROP PRIMARY KEY
or DROP INDEX key_name
or RENAME [AS] new_tbl_name
or table_option
範例:
 欄位重新命名
 mysql> ALTER TABLE t1 CHANGE a b INTEGER;
  將資料表 t1 欄位 a 改名為 b (其資料型態是 integer)
 改變欄位資料型態
 mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
 mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
  將資料表 t1 欄位 b 的資料型態改為 bigint not null 

 mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10)); 
 mysql> ALTER TABLE t1 RENAME t2;
  將資料表 t1 改名為 t2
 mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
  將資料表 t2 欄位 a 資料型態由 integer 改為 tinyint not null ,欄位 b 改名為 c 資料型態改為 char(20)
 mysql> ALTER TABLE t2 ADD d TIMESTAMP;
  在資料表 t2 增加新欄位 d 資料型態是 timestamp
 mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);
  在資料表 t2 ,對 d 欄位做索引,並以欄位 a 作為主索引鍵
 mysql> ALTER TABLE t2 DROP COLUMN c;
  刪除欄位 c
 mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD INDEX (c);
  新增欄位 c,並做索引(做索引的欄位必須為 not null )

資料表最佳化 OPTIMIZE TABLE 資料表名
語法:OPTIMIZE TABLE tbl_name
 欄位長度有變動、刪除大量資料,都應進行資料表最佳化

三、紀錄的操作

插入一筆或多筆紀錄 INSERT INTO 資料表(欄位1,欄位2,......) VALUES(值1,值2,......), (值1,值2,......), ........
  (MySQL 3.22.5 以後可插入多筆記錄)
語法:
INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name [(col_name,...)]
VALUES (expression,...),(...),...
or INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
or INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name
SET col_name=expression, col_name=expression, ...
範例:
 mysql> INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
  不可寫成
 mysql> INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
  因為:欄位 col1 的值先填入後,才可以計算欄位 col2

從檔案讀入資料
語法:
 LOAD DATA [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE]
INTO TABLE tbl_name
[FIELDS
[TERMINATED BY '\t']    每一欄位以某字元分開(內定是 tab)
[OPTIONALLY] ENCLOSED BY "]   每一欄位以某字元括住(內定是不使用括號)
[ESCAPED BY '\\' ]]     
[LINES TERMINATED BY '\n']  設定換行的字元(內 定是 \n)
[IGNORE number LINES]    忽略最前面幾行(最前面幾筆記錄不抄進來)
[(col_name,...)]
範例:
 mysql> USE db1;
 mysql> LOAD DATA INFILE "./data.txt" INTO TABLE db2.my_table;
  從目前 MySQL 目錄讀入 data.txt
 mysql> LOAD DATA INFILE "./88.txt" INTO TABLE TEACHER FIELDS TERMINATED BY ' ' ;
  從目前 MySQL 目錄(我的在 /var/lib/mysql )讀入 data.txt ,每一欄位以 空白 分開
 mysql> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata (col1,col2,...);
  只將 persondata.txt 裡某些欄位的資料抓過來 

刪除紀錄 DELETE [LOW-PRIORITY] FROM 資料表名 WHERE 條件 [LIMIT rows]
語法:
 DELETE [LOW_PRIORITY] FROM tbl_name
[WHERE where_definition] [LIMIT rows]
  LOW-PRIORITY 是等到沒有用戶端使用時再刪
  LIMIT rows 限制刪除紀錄的筆數
範例:
 mysql> DELETE FROM 資料表名;
  刪除所有紀錄
 mysql> DELETE FROM 資料表名 WHERE 1>0;
  刪除所有紀錄,但速度較慢,方便在螢幕上看

更新一筆紀錄 (語法與 INSERT 相同)
 REPLACE INTO 資料表(欄位1,欄位2,......) VALUES(值1,值2,......)
語法:
REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name [(col_name,...)]
VALUES (expression,...)
or REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name [(col_name,...)]
SELECT ...
or REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name
SET col_name=expression, col_name=expression,...

更新多筆紀錄
語法:
UPDATE [LOW_PRIORITY] tbl_name SET col_name1=expr1,col_name2=expr2,... [WHERE where_definition]
  如果沒有設定 WHERE 條件,則整個資料表相關的欄位都更新
範例:
 mysql> UPDATE persondata SET age=age+1;
  將資料表 persondata 中,所有 age 欄位都加 1
 mysql> UPDATE persondata SET age=age*2, age=age+1;
  將資料表 persondata 中,所有 age 欄位都*2,再加 1

四、資料的輸出

SELECT

語法:
 SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [DISTINCT | ALL]
select_expression,...
[INTO OUTFILE 'file_name' export_options]
[FROM table_references
[WHERE where_definition]
[GROUP BY col_name,...]
[HAVING where_definition]
[ORDER BY {unsigned_integer | col_name} [ASC | DESC] ,...]
[LIMIT [offset,] rows]
[PROCEDURE procedure_name] ]

範例:

排序輸出
select * from 資料表名 order by 欄位名1,欄位名2,欄位名3...... 

反向排序輸出
select * from 資料表名 order by 欄位名1,欄位名2,欄位名3...... desc

 

mysql> select concat(last_name,', ',first_name) AS full_name

      from mytable ORDER BY full_name;



 mysql> select t1.name, t2.salary from employee AS t1, info AS t2

where t1.name = t2.name;

  顯示資料庫 employee(別名 t1) 裡,資料表 t1 的欄位 name 和 資料表 t2 的欄位 salary 當.....

 mysql> select t1.name, t2.salary from employee t1, info t2 where t1.name = t2.name;



 mysql> select college, region, seed from tournament

ORDER BY region, seed;

 mysql> select college, region AS r, seed AS s from tournament

ORDER BY r, s;

 mysql> select college, region, seed from tournament

ORDER BY 2, 3;



 mysql> select col_name from tbl_name HAVING col_name > 0;



 mysql> select col_name from tbl_name WHERE col_name > 0;



 mysql> select user,max(salary) from users

group by user HAVING max(salary)>10;



mysql> select user,max(salary) AS sum from users

group by user HAVING sum>10;



 mysql> select * from table LIMIT 5,10; # Retrieve rows 6-15



 mysql> select * from table LIMIT 5; # Retrieve first 5 rows

  •  

在命令列下進行批次處理:
shell> mysql -h host -u user -p < batch-file
Enter password: ********

Type Bytes From To
TINYINT 1 -128 127
SMALLINT 2 -32768 32767
MEDIUMINT 3 -8388608 8388607
INT 4 -2147483648 2147483647
BIGINT 8 -9223372036854775808 9223372036854775807

Column type ``Zero'' value
DATETIME '0000-00-00 00:00:00'
DATE '0000-00-00'
TIMESTAMP 00000000000000 (length depends on display size)
TIME '00:00:00'
YEAR 0000

Column type Display format
TIMESTAMP(14) YYYYMMDDHHMMSS
TIMESTAMP(12) YYMMDDHHMMSS
TIMESTAMP(10) YYMMDDHHMM
TIMESTAMP(8) YYYYMMDD
TIMESTAMP(6) YYMMDD
TIMESTAMP(4) YYMM
TIMESTAMP(2) YY

Type Max.size Bytes
TINYTEXT or TINYBLOB 2^8-1 255
TEXT or BLOB 2^16-1 (64K-1) 65535
MEDIUMTEXT or MEDIUMBLOB 2^24-1 (16M-1) 16777215
LONGBLOB 2^32-1 (4G-1) 4294967295

Value CHAR(4) Storage required VARCHAR(4) Storage required
'' ' ' 4 bytes '' 1 byte
'ab' 'ab ' 4 bytes 'ab' 3 bytes
'abcd' 'abcd' 4 bytes 'abcd' 5 bytes
'abcdefgh' 'abcd' 4 bytes 'abcd' 5 bytes

Value Index
NULL NULL
"" 0
"one" 1
"two" 2
"three" 3

Other vendor type MySQL type
BINARY(NUM) CHAR(NUM) BINARY
CHAR VARYING(NUM) VARCHAR(NUM)
FLOAT4 FLOAT
FLOAT8 DOUBLE
INT1 TINYINT
INT2 SMALLINT
INT3 MEDIUMINT
INT4 INT
INT8 BIGINT
LONG VARBINARY MEDIUMBLOB
LONG VARCHAR MEDIUMTEXT
MIDDLEINT MEDIUMINT
VARBINARY(NUM) VARCHAR(NUM) BINARY

Column type Storage required
TINYINT 1 byte
SMALLINT 2 bytes
MEDIUMINT 3 bytes
INT 4 bytes
INTEGER 4 bytes
BIGINT 8 bytes
FLOAT(X) 4 if X <= 24 or 8 if 25 <= X <= 53
FLOAT 4 bytes
DOUBLE 8 bytes
DOUBLE PRECISION 8 bytes
REAL 8 bytes
DECIMAL(M,D) M+2 bytes if D > 0, M+1 bytes if D = 0 (D+2, if M <>)
NUMERIC(M,D) M+2 bytes if D > 0, M+1 bytes if D = 0 (D+2, if M <>)

Column type Storage required
DATE 3 bytes
DATETIME 8 bytes
TIMESTAMP 4 bytes
TIME 3 bytes
YEAR 1 byte

Column type Storage required
CHAR(M) M bytes, 1 <= M <= 255
VARCHAR(M) L+1 bytes, where L <= M and 1 <= M <= 255
TINYBLOB, TINYTEXT L+1 bytes, where L <>
BLOB, TEXT L+2 bytes, where L <>
MEDIUMBLOB, MEDIUMTEXT L+3 bytes, where L <>
LONGBLOB, LONGTEXT L+4 bytes, where L <>
ENUM('value1','value2',...) 1 or 2 bytes, depending on the number of enumeration values (65535 values maximum)
SET('value1','value2',...) 1, 2, 3, 4 or 8 bytes, depending on the number of set members (64 members maximum)




常用JDBC连接用字符串

常用JDBC连接用字符串

descript:各种常用数据库的jar,用于Java数据库连接

1) SQLServer2000:驱动包(msbase.jar mssqlserver.jar msutil.jar)
url: jdbc:microsoft:sqlserver://localhost:1433;databasename=pubs
driver: com.microsoft.jdbc.sqlserver.SQLServerDriver

2) SQLServer2005:驱动包(sqljdbc.jar)
url: jdbc:sqlserver://localhost:1433;databasename=pubs
driver: com.microsoft.sqlserver.jdbc.SQLServerDriver


===============================================================================

3) JTDS -----SQLServer(支持SQL2000和SQL2005)
url: jdbc:jtds:sqlserver://localhost:1433/pubs
driver: net.sourceforge.jtds.jdbc.Driver


4) Oracle:驱动包(classes12.jar)
url: jdbc:oracle:thin:@0735jb:1521:aptech
(语法:jdbc:oracle:thin:@[ip]:[port]:[sid])
driver: oracle.jdbc.driver.OracleDriver


5) mysql:驱动包(mysql-connector-java-3.1.12-bin.jar)
url: jdbc:mysql: //127.0.0.1:3306/mysql

driver:org.gjt.mm.mysql.Driver

IE和Firefox在JavaScript方面的兼容性(汇编)

IEFirefoxJavaScript方面的兼容性(汇编)

IEFirefoxJavaScript方面的兼容性(汇编)

1.document.formName.item("itemName") 问题

说明:IE,可以使用document.formName.item("itemName")document.formName.elements["elementName"];Firefox,只能使用document.formName.elements["elementName"].

解决方法:统一使用document.formName.elements["elementName"].

2.集合类对象问题

说明:IE,可以使用()[]获取集合类对象;Firefox,只能使用[]获取集合类对象.

解决方法:统一使用[]获取集合类对象.

3.自定义属性问题

说明:IE,可以使用获取常规属性的方法来获取自定义属性,也可以使用getAttribute()获取自定义属性;Firefox,只能使用getAttribute()获取自定义属性.

解决方法:统一通过getAttribute()获取自定义属性.

4.eval("idName")问题

说明:IE,,可以使用eval("idName")getElementById("idName")来取得ididNameHTML对象;Firefox下只能使用getElementById("idName")来取得ididNameHTML对象.

解决方法:统一用getElementById("idName")来取得ididNameHTML对象.

5.变量名与某HTML对象ID相同的问题

说明:IE,HTML对象的ID可以作为document的下属对象变量名直接使用;Firefox下则不能.Firefox,可以使用与HTML对象ID相同的变量名;IE下则不能。

解决方法:使用document.getElementById("idName")代替document.idName.最好不要取HTML对象ID相同的变量名,以减少错误;在声明变量时,一律加上var,以避免歧义.

6.const问题

说明:Firefox,可以使用const关键字或var关键字来定义常量;IE,只能使用var关键字来定义常量.

解决方法:统一使用var关键字来定义常量.

7.input.type属性问题

说明:IEinput.type属性为只读;但是Firefoxinput.type属性为读写.

8.window.event问题

说明:window.event只能在IE下运行,而不能在Firefox下运行,这是因为Firefoxevent只能在事件发生的现场使用.

解决方法:

IE:

...

IE&Firefox:

...

9.event.xevent.y问题

说明:IE,even对象有x,y属性,但是没有pageX,pageY属性;Firefox,even对象有pageX,pageY属性,但是没有x,y属性.

解决方法:使用mX(mX = event.x ? event.x : event.pageX;)来代替IE下的event.x或者Firefox下的event.pageX.

10.event.srcElement问题

说明:IE,even对象有srcElement属性,但是没有target属性;Firefox,even对象有target属性,但是没有srcElement属性.

解决方法:使用obj(obj = event.srcElement ? event.srcElement : event.target;)来代替IE下的event.srcElement或者Firefox下的event.target.

11.window.location.href问题

说明:IE或者Firefox2.0.x,可以使用window.locationwindow.location.href;Firefox1.5.x,只能使用window.location.

解决方法:使用window.location来代替window.location.href.

12.模态和非模态窗口问题

说明:IE,可以通过showModalDialogshowModelessDialog打开模态和非模态窗口;Firefox下则不能.

解决方法:直接使用window.open(pageURL,name,parameters)方式打开新窗口。

如果需要将子窗口中的参数传递回父窗口,可以在子窗口中使用window.opener来访问父窗口. 例如:var parWin = window.opener; parWin.document.getElementById("Aqing").value = "Aqing";

13.frame问题

以下面的frame为例:

(1)访问frame对象:

IE:使用window.frameId或者window.frameName来访问这个frame对象.

Firefox:只能使用window.frameName来访问这个frame对象.

另外,在IEFirefox中都可以使用window.document.getElementById("frameId")来访问这个frame对象.

(2)切换frame内容:

IEFirefox中都可以使用window.document.getElementById("testFrame").src = "xxx.html"window.frameName.location = "xxx.html"来切换frame的内容.

如果需要将frame中的参数传回父窗口,可以在frme中使用parent来访问父窗口。例如:parent.document.form1.filename.value="Aqing";

14.body问题

Firefoxbodybody标签没有被浏览器完全读入之前就存在;而IEbody则必须在body标签被浏览器完全读入之后才存在.

例如:

Firefox

IE&Firefox

15. 事件委托方法

IEdocument.body.onload = inject; //Function inject()在这之前已被实现

Firefoxdocument.body.onload = inject();

有人说标准是:

document.body.onload=new Function('inject()');

16. firefoxIE(parentElement)的父元素的区别

IEobj.parentElement

firefoxobj.parentNode

解决方法: 因为firefoxIE都支持DOM,因此使用obj.parentNode是不错选择.

17.cursor:hand VS cursor:pointer

firefox不支持hand,但ie支持pointer

解决方法: 统一使用pointer

18.innerTextIE中能正常工作,但是innerTextFireFox中却不行.

解决方法:

if(navigator.appName.indexOf("Explorer") > -1){

document.getElementById('element').innerText = "my text";

} else{

document.getElementById('element').textContent = "my text";

}

19. FireFox中类似 obj.style.height = imgObj.height 的语句无效

解决方法:

obj.style.height = imgObj.height + 'px';

Python 3.0更新内容

2007年8月31日,Python 3000的最新版本Py3.0终于释出了第一个alpha版本。因为3.0版本与之前的2.x版本不兼容,所以,Py3.0版本完全可以看作是Py的新 生。此实为Python社区盛事。虽然Py3.0的final版本要到08年8月才会释出,但我们仍然可以从a1版本看到很多Py3.0的新特性,现在我 们就来体验一下。

  下载与安装

  在http://www.python.org/download/releases/3.0/下载。提供压缩的源代码包(50MB)和Windows安装包(10MB)。

  兼容性

  早在Py3.0释出之前,Guido就放言Py3.0不再对Py2.x兼容。现在看来,的确是这样的。

  不过,提供了一个“2To3”的转换器,以便开发人员能够将Py2.x的代码转到Py3.0上来。但目前这个还没有正式的释出版本,只有SVN 仓库可以CheckOut。地址在这里:http://svn.python.org/view/sandbox/trunk/2to3/

  性能

  Py3.0运行pystone benchmark的速度比Py2.5慢30%。Guido认为Py3.0有极大的优化空间,在字符串和整形操作上可以取得很好的优化结果。

  编码

  Py3.0源码文件默认使用utf-8编码,这就使得以下代码是合法的:

  >>> 中国 = 'china'

  >>> print(中国)

  china

  语法:

  1)去除了<>,全部改用!=。

  2)去除``,全部改用repr()

  3)关键词加入as和with。

  4)整型除法返回浮点数,要得到整型结果,请使用//。

  5)加入nonlocal语句。使用noclocal x可以直接指派外围(非全局)变量。

  6)去除print语句,加入print()函数实现相同的功能。同样的还有exec语句,已经改为exec()函数。

  7)去除元组参数解包。不能def(a, (b, c)):pass这样定义函数了。

  8)新式的8进制字面量,相应地修改了oct()函数。2.x这样:

  >>> 0666

  438

  >>> oct(438)

  '0666'

  3.0这样:

  >>> 0666

  SyntaxError: invalid token (, line 1)

  >>> 0o666

  438

  >>> oct(438)

  '0o666'

  9)增加了2进制字面量和bin()函数:

  >>> bin(438)

  '0b110110110'

  >>> _438 = '0b110110110'

  >>> _438

  '0b110110110'

  10)扩展的可迭代解包。在Py3.0里,a, b, *rest = seq 和 *rest, a = seq都是合法的,只要求两点:rest是list对象和seq是可迭代的。

  11)新的super(),可以不再给super()传参数,

  >>> class C(object):
  def __init__(self, a):
  print(
'C', a)
  
>>> class D(C):
  def __init(self, a):
  super().__init__(a) # 无参数调用super()
  
>>> D(8)
  C
8
  
<__main__.D object at 0x00D7ED90>

  12) 新的metaclass语法:

  class Foo(*bases, **kwds):
  pass

  13)支持class decorator。用法与函数decorator一样:

  >>> def foo(cls_a):
  def print_func(self):
  print(
'Hello, world!')
  cls_a.print
= print_func
  
return cls_a
  
>>> @foo
  
class C(object):
  pass
  
>>> C().print()
  Hello, world
!

  class decorator可以用来玩玩狸猫换太子的大把戏。

  14)raise语句的语法改变。

  字符串和字节串

  1)Py3.0去除了unicode类型,现在字符串只有str一种类型,但它跟2.x版本的unicode几乎一样。

  2)关于字节串。

  数据类型

  1)Py3.0去除了long类型,现在只有一种整型——int,但它的行为就像2.x版本的long。

  2)新增了bytes类型,对应于2.x版本的八位串,定义一个bytes字面量的方法如下:

  >>> b = b'china'
  
>>> type(b)
  str对象和bytes对象可以使用.encode() (str
-> bytes) or .decode() (bytes -> str)方法相互转化。
  
>>> s = b.decode()
  
>>> s
  
'china'
  
>>> b1 = s.encode()
  
>>> b1
  b
'china'

  3)dict的.keys()、.items和.values()方法返回迭代器,而之前的iterkeys()等函数都被废弃。同时去掉的还有dict.has_key(),用in替代它吧!

  面向对象

  1)引入抽象基类(Abstraact Base Classes,ABCs)。

  2)容器类和迭代器类被ABCs化,所以cellections模块里的类型比Py2.5多了很多。

  >>> import collections
  
>>> print('\n'.join(dir(collections)))
  Callable
  Container
  Hashable
  ItemsView
  Iterable
  Iterator
  KeysView
  Mapping
  MappingView
  MutableMapping
  MutableSequence
  MutableSet
  NamedTuple
  Sequence
  Set
  Sized
  ValuesView
  __all__
  __builtins__
  __doc__
  __file__
  __name__
  _abcoll
  _itemgetter
  _sys
  defaultdict
  deque

  另外,数值类型也被ABCs化。关于这两点。

  3)迭代器的next()方法改名为__next__(),并增加内置函数next(),用以调用迭代器的__next__()方法

  4)增加了@abstractmethod 和 @abstractproperty两个decorator,编写抽象方法(属性)更加方便。

  异常

  1)所以异常都从BaseException继承,并删除了StardardError。

  2)去除了异常类的序列行为和.message属性。

  3)用raise Exception(args) 代替 raise Exception, args语法。

  4)捕获异常的语法改变,引入了as关键字来标识异常实例,在Py2.5中:

  >>> try:
  ... raise NotImplementedError(
'Error')
  ... except NotImplementedError, error:
  ... print error.message
  ...
  Error

  在Py3.0中:

  >>> try:
  raise NotImplementedError(
'Error')
  except NotImplementedError
as error: # 注意这个 as
  print(str(error))
  Error

  5)异常链,因为__context__在3.0a1版本中还没有实现,这方面就不说了。

  其它:

  1)xrange()改名为range(),要想使用range()获得一个list,必须显式调用:

  >>> list(range(10))

  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

  2)bytes对象不能hash,也不支持b.lower()、b.strip()和b.split()方法,但对于后两者可以使用b.strip(b’ \n\t\r\f’)和b.split(b’ ‘)来达到相同目的。

  3)zip()、map()和filter()都返回迭代器。而apply()、callable()、coerce()、execfile()、reduce()和reload()函数都被去除了。

  4)string.letters和相关的.lowercase和.uppercase被去除,请改用string.ascii_letters等。

  5)如果x <>

  6)__getslice__系列成员被废弃。a[i:j]根据上下文转换为a.__getitem__(slice(I, j))或__setitem__和__delitem__调用。

  7)file类被废弃,在Py2.5:

  >>> file
  在Py3.
0
  
>>> file
  Traceback (most recent call last):
  File
"", line 1, in
  file
  NameError: name
'file' is not defined

  感想

  Python 3.0版本是Python的革命性升级,废除了许多之前的特性,也引入了新特性(如大量使用迭代器的思想)。开发人员从2.x升级到3.0版本需要比较大的代价,不仅要重新训练自己已经僵化的手指,更要让脑子从以前的条条框框中跳出来。

  现在释出的只是alpha 1版本,还有很多特性都没有实现,根据PEP 3000的计划,到08年4月将能够实现全部新特性,到时我们将会有更强的震憾感吧?