从c++转到Python需要注意的地方

下面的资料,会随着学习的不断深入,持续的更新。

内容没有能有效的组织,因为没一点是本人再学习的过程中,慢慢的总结出来的。等本篇文字足够长的时候,可能会考虑组织文件可读性更强的文字。

 

1. c/c++里面,注释代码是用 // ,而python是用 #

 

 2. c/c++里面,定义类对象

 

// define class
class ClassA
{
...
};
//////////////////////////////////////////////////////////////
ClassA OA; // 对象
ClassA *pA = new ClassA; // 指针

而python里面

# define class
class ClassA:
    def func( self, name ):
        #do something

 
# declare a object of the class
ca = ClassA()

ca.func( 'myname' )

 

3.  c/c++主要依靠语句开始结束来判定语句块,如 “{ } , ;”这些。 而python靠的是缩进,缩进四个空格,不是一个tab,因为tab根据所使用的文本编辑不一样,所代表的空格数量不一样,有些是4,有些是8.

 

4. python类的成员函数都必须有一个self的参数传进去,self相当于c/c++的this。也就意味着成员函数至少有一个参数,不想c/c++可以没有参数。

 

5. 继承语法不一样,下面看下的python的类继承。

class ClassA:
    def funca( self, name ):
        #do something

class ClassB(ClassA):
    def funcb( self, name ):
        #do something

 6. python没有main函数,我们的c/c++都是以main为入点函数。但是python没有入点函数,而是从py文件的第一行就开始执行

 

7. c/c++里面字符串是用双引号””来修饰,而python则是用单引号 ”, 或者是双引号””

char *p = "hello";

p='hello'

 

8.  打印语句,print在2.7以前的版本print可以写成:

print ‘hello world’

或者

print ( ‘hello world’ )

但是2.7以后第一种格式不被支持。

 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

下面给些样例代码,windows下面这些代码你可以直接ctrl+c, ctrl+v到你的记事本,然后保存成以py为后缀的文件你就可以直接执行;linux下面将下面的这些代码拷贝到一个新建的以py为后缀的文件,在文件的最开始加上#!/usr/bin/python,这行代码其实就是指定要用那个python解释器去执行该脚本。

 

# test simple print 
print 'hello world'
name = 'myname'
print 'hello %s' %name

# define variables
max=10000
min=1
useridbase='2012FFD_'

# define a function to print string
def MyPrint( str ):
 print str
 
# define a function to do somthing
def UpdateUserID( id ):
 idd = id + 1
 idCur = '%s' %idd
 useridCurrent = useridbase+idCur
 print 'user name: %s' %useridCurrent
 return id+1

# define class
class cTest1:
 def func1( self, name ):
  print 'hello %s', name
 def add( self, a, b ):
  return a + b
  
# test class
c1=cTest1()
c1.func1('my class')
res = c1.add(3,22)
print 'sum is %s' %res
 
# for loop, and call funtions we defined above
for n in xrange( min, max ):
 str = 'now user with no %s login' %n
 MyPrint( str )
 UpdateUserID( n )


 


 


9.  全局变量,python中使用全局变量时必须加上global关键字,否则被视为局部变量或者未定义。

g_user = 0

def UseGlobalVar():
    global g_user
    if ( g_user == 0 ):
        #do something

10. 如果忘了给变量/对象赋值,直接使用这个对象的方法就会被告知,这个对象没有这个方法。

这点很让我恶心,也是c/c++转过来的人很难适应的地方,在c/c++中,这个对象有没有这个方法主要看这个对象对应的类,有没有这个方法。为什么python不能提供像javascript的那种特性,既可以定义为无类型,也可以定义某一类型的变量。也正因为这样,python的类型可以几乎没有。

class classA:
    def func( self ):
        # do something here

Obj_classA = None

print( 'testing start' )
#Obj_classA = new ClassA()
Obj_class.func()

 

其实如果说提示的是Obj_classA这个对象没有一个对应的类型,还是可以理解的。而不是没有这个方法。

 

11. python中变量可以赋任意类型的值

var = 12
var = 'hello'
var = [ 3, 2, 22 ]
print ( var )

上面这些代码没有任何问题,最后打印出的是 [3 , 2, 22 ].

其实这点我很不喜欢,弱类型或者无类型就有可能导致一些bug,而不容易被查出。

 

12. 求地址,c/c++通过&, 而python通过一个函数id函数

a = 1
b = a
print( id( a ))
print( id( b ))

 

id()这个函数返回的是对象的全部唯一标识符,是整型或者长整型的数字,可以看做是对象的地址。

 

 

13. 命名空间。c/c++是通过namespace关键字来定义和使用,而python中,这个东西没有用特别的关键字表示,而是一个python脚本文字自动被认为一个命名空间,而这个命名空间的名字就是文件的名字

如我们有2个文件,一个定义函数和变量,另外一个则使用这些函数和变量。

#FuncAssembly.py

count = 0

def UserPass():
    global count
    count++
    return count

def UserCancel():
    global count
    count--
    return count

 

import FuncAssembly
#from FuncAssembly import *
#from FuncAssembly import UserPass

print( 'start testing' )
res = FuncAessembly.UserPass() 
print( res )

 

看到了吧,第二个文件要使用第一文件,只要import进来就可以了,import有点类似c/c++的#include。这个时候第一个文件的文件名就是它的命名空间,使用它的变量或者函数的时候,必须加上命名空间。

 

14. python的与或关系不是c/c++的 && 和 ||。而是直接使用自然语言 and 和 or

 

a = 1
b = 2
if (( a==1 ) and ( b == 2 )):
    print( 'all are correct' )

if (( a == 1 ) or ( b == 3 )):
    print( 'some a is correct' )

 

15. python中等于和不等于除了可以用==和!=来表示,还可以直接使用自然语言 is 和 is not  

a = 1
if ( a is 1 ):
   print( 'is' )
if ( a is not 2 ):
    print( 'not' )

 

16. python的关键字:

and

del

from

not

while

as

elif

global

or

with

assert

else

if

pass

yield

break

except

import

print

class

exec

in

raise

continue

finally

is

return

def

for

lambda

try

None

 

17. 字符串加和操作。python中字符串可以简单的加和:

str1 = 'hello ' + 'world'
str2 = 'hello' 'world'
print ( str1 )
print ( str2 )

 

这里顺便说下str是python的内置类型,所以不要把你的变量的名字定义为str。

上面的str1和str2的内容是一样,2中字符串的连接是等效的。但是第二种方式的操作符不能使变量,即:

str3 = 'simple'

str2 = str3 'string' #语法错误

是不可以的。必须要用第一种:

str3 = 'simple'

str2 = str3 + 'string'

 

格式化字符串也很方便:

a = 1
b = 'string'
ss = 'ss string is {0} and {1}'.format( a, b )
print( ss )

 

上面的结果是

ss string is 1 and string

 

18. 格式化字符串

str1 = 'hello'
str2 = 'world'
num1 = 8
str3 = '%(string1)s my %(string2)s, integer is %(number1)03d' %{'string1':str1, 'string2':str2, 'number1':num1}
print( str3 )

 

上面输出的结果是

hello my world, integer is 008

 

19. python中,没有public, protected, private来描述class的成员,而是通过成员的前缀来区分是public的还是private的,如果有 ‘__’(注意是2个下划线)就表示私有的,如果没有就是公有的。

class myclass:
    name = ''
    __name1 = ''
    def __privatefunc( sef ):
        print( 'cannot be called outside' )
    def ini( self ):
        print( 'hello' )
    def create( self, name ):
        self.name = name
        print( 'now create' )


mc = myclass()
mc.ini()
mc.create( 'myname' )
mc.name = 'changed'
mc.__privatefunc() #错误

mc.__name1 = 'name' #错误

 

上面的代码声明了__name1和__privatefunc()为私有的,因此最后两句会导致错误。

不过要说一下,python这里是做了一个小把戏,其实是在运行时修改了这种属性的名字,该规则是 _类名+属性名,在上面的例子中改后的名字为:

_myclass_privatefunc,知道了这个规则后,就可以访问到这个所谓的私有方法。其实用python内置的方法 dir()就可以看到改变的名字。

 

20. python不可以像c/c++那样,进行强制类型转换但是可以像下面那样构造一个新的对象来达到这种效果

s1='hello world'
l1=(list)s1  #错误
l1=list(s1)  #正确

 

21. ++和--在python不支持,如果做到同样的效果改为 +=和 -=
 

a = 1L
a++  #错误
a += 1L #正确

22. python中不能用static来定义一个静态方法(c++中就是这样定义的),static不是python的关键字。但是python还是可以定义静态方法的:

class classA:
    @staticmethod
    def func( s ):
        print( s )

classA.func( 'test' )

但是不要想当然的,使用@staticvariable来定义静态成员变量,python中是不可以定义静态变量的。

23. python中不用显示写函数的返回类型,或者表明函数返回一个东西. 并且默认会返回一个None,如果你的函数没有写任何return语句的话,否则返回你自己的类型。None是python的关键字。

 
def func():
    print( 'simple test' )

if ( None == func()):
    print( 'correct' )

 

24. c++和python都是面向对象的语言,那么就自省的能力,至于什么自省的能力,请参看我的另外一篇文章。C++的自省是依靠typeid(),而python是通过2个内置的方法:isinstance()和hasattr()

class CA:
    x = 'name'
    def func( self ):
        print( x )

a = CA()
print( isinstance( a, CA ))    输出->True
print( hasattr( a, 'func' ))   输出->True

 

 

25. python可以直接在类中嵌入类的说明,然后通过 __doc__来访问说明:

class CA( object ):
    "used to test a class that is derived from base class-object"
    def func( this ):
        print( 'this is ref to object' )

a = CA()
print( a.__doc__ )  输出->"used to test a class that is derived from base class-object"

 

26. python中,类的继承过程中,可以把类中所有方法视为c++的虚函数。 

class CA:
    "the class is designed to test a class is defined without being derived from base class object"
    x = 0L
    @classmethod
    def func( sef ):
        print( "CA func" )
        
    @classmethod
    def func1( self ):
        print( "CA func1" )
        
    @classmethod
    def __privateFunc( self ):
        print( "CA private func " )

    @staticmethod
    def staticfunc():
        print( "CA static function" )

class CCA( CA ):
    def func( slef ):
        print( "CCA func" )

print( 'test class derivation' )
cca = CCA()
cca.func()     #输出->CCA func

 

27. c++的构造函数和析构函数的名字基于类的名字,但是python的构造函数固定为 __init__(),析构函数固定为 __del__()。详细的内容请参看我的另外一篇博文:

http://blog.csdn.net/huangxiansheng1980/article/details/7227915

 

  

28. python的函数参数可以任意的顺序传进去如果指定了参数的名字

下面是测试代码:

def simplefunc( d, username, password ):
        print( 'id:{0}'.format( d ) )
        print( 'username:{0}'.format( username ))
        print( 'password:{0}'.format( password ))

def testsimple():
        i = 1
        un = 's1'
        pw = '123'
        print 'test1=================='
        simplefunc( i, un, pw )
        print 'test2=================='
        simplefunc( username=un, password=pw, d=i)
        print 'test3==================='
        simplefunc( password=pw, d=i, username=un)

>>> from funcDef import *
>>> testsimple()
test1==================
id:1
username:s1
password:123
test2==================
id:1
username:s1
password:123
test3===================
id:1
username:s1
password:123

未完待续...



















版权所有,禁止转载. 如需转载,请先征得博主的同意,并且表明文章出处,否则按侵权处理.

    分享到:

Leave a Reply

Your email address will not be published. Required fields are marked *