一 Python简单介绍

Python是一个可移植的面向对象的脚本语言。

Python尽管是一个脚本语言,但也是一个全然面向对象的语言。由于它设计之初把易用性做为很重要的一个考量标准,所以用起来很简洁,优美(语法很灵活),所以使用Python能够高速地编写出可执行代码。

与C/C++相比,Python程序的执行速度比較慢,一门语言既然能够生存下来。就有它自己的原因,Python语言也一样。当今的计算机处理速度已经很快,对某些任务来说,执行速度并非首要考虑的因素。比方说为了实现数据库訪问的自己主动化,须要做一个数据库訪问的代码生成器,这是一个常见的任务,当中涉及编程的很多方面,包含字符串处理、数据库訪问,可能还包含一个GUI系统。

这个任务显然不太适合用C或者C++来编写。由于使用C/C++来开发尽管能够节省那么一点执行时间,但却浪费了大量的开发时间。所以,语言没有好不好之分,仅仅有适合不适合之分。

C++是静态强类型语言,而Python是动态强类型语言。因为是动态语言,所以变量的类型不是用keyword显式指定,而是在执行时依据赋给它的值动态推断出来的。

      另外,Python也跟C++一样同一时候支持结构化编程和面向对象编程两种范式。 Python的特定总结例如以下:

1. Python是面向对象的。它支持继承以及多重继承、多态、操作符重载等面向对象的概念。

2. Python是可移植的。使用Python语言编写的程序通常无需改动就能够执行在多个平台上,这点与Java类似。

可是Python也提供一些Plantform dependent的模块,使用这些模块的时候必须小心,由于他们是不可移植的。

3. Python是解释性语言。准确地说,Python先把源程序编译成中间代码(类似于java和c#)。然后解释运行。

但要注意的是。编译过程对程序猿来说是透明的(这又不同于java和c#)。

4.Python是一门动态语言。它支持元数据编程;支持执行时编译、执行等现代语言的高级特征。这些都非常难甚至无法在C/C++中实现。Python甚至同意你在执行的时候添加一个对象的成员!

5. 一切都是对象!

Python中对象的概念比其它语言丰富得多,比方类是一个对象,因此你能够在执行的时候使用它,而不像C++一样,类是编译时的对象。

正由于这样的原因,使得Python是高度动态的。

6. 自己主动内存管理。像java一样。你无需管理你的代码所使用的内存。在C和C++的程序中,那是一场恶梦。

7. 其它:Python能够使用c/c++的编写的组件,也能够把python代码嵌入到c/c++代码中运行。

二 类定义
首先看以下的样例

class ZZClass:

     classNum = 0

     def __init__(self):

          self.num = 1

          ZZClass.classNum += 1

          print ("ZZClass _init__ called.")





     def __del__(self):

          ZZClass.classNum -= 1;

          print ("ZZClass __del__ called.")



     def Hello(self):

          print("hello world!")

          self.PrintClassNum(10) #普通函数中能够调用静态函数





     def setNum(self,num):

          self.num = num



     def getNum(self):

          return self.num



     @staticmethod

     def PrintClassNum(num=100):

          print (ZZClass.classNum) #在静态方法中仅仅能通过类名訪问类变量

          #print classNum          #在静态方法中不能直接訪问类变量

          #print self.num          #在静态方法中不能訪问实例变量

          print num





     @classmethod

     def ClassMethod(cls):

          #print cls.num           #在类方法中不能直接訪问实例变量

          print "class method."

          print cls.classNum       #在类方法中能够直接訪问类变量





myObj = ZZClass()

myObj.Hello()

ZZClass.PrintClassNum(10) #能够通过类名来訪问静态方法

myObj02  = ZZClass()

myObj02.PrintClassNum()   #能够通过对象实例来訪问静态方法

print myObj.classNum      #能够通过对象实例来訪问类变量

print ZZClass.classNum    #能够通过类名来訪问静态变量









myObj.setNum(10)

myObj02.setNum(20)

print myObj.getNum()

print myObj02.getNum()



myObj02 = 0

print ZZClass.PrintClassNum()



print ZZClass.ClassMethod() #通过类调用类方法

print myObj.ClassMethod()   #通过实例调用类方法





输出结果:

ZZClass _init__ called.

hello world!
1
10
1
10
ZZClass _init__ called.
2
100
2
2
10
20
ZZClass __del__ called.
1
100
None
class method.
1
None
ZZClass __del__ called. 


分析:
1.与C++相比,Python中定义方法採用defkeyword。在类中定义的方法至少会有一个參数。一般以名为'self'的变量作为该參数(用其它名称也能够)。并且须要作为第一个參数。用于对对象的变量引用。类似c++的this指针,仅仅只是在C++中this
指针是隐藏的,由编译器来处理。

2.函数调用和变量的訪问使用"."而不是"->"訪问。
3._init__类似于构造函数,在生成对象时调用,能够用来进行一些初始化操作,不须要显示去调用,系统会默认去运行。构造方法支持重载。假设用户自己没有又一次定义构造方法。系统就自己主动运行默认的构造方法。
   __del__类似于析构函数。在释放对象时调用,支持重载,能够在里面进行一些释放资源的操作,不须要显示调用。

4.实例变量和类变量:num是实例变量。classNum是类变量。前者类似C++的成员变量,后者类似C++的类的静态变量。类变量是全部对象共享的,不须要对象,能够直接用“类名.变量名”訪问,与C++一样。使用对象实例也能够訪问类变量。实例变量是每一个对象一个拷贝。仅仅能通过对象訪问,实例变量是不须要在类中显示定义的。
     注意:类变量能够通过类名和实例对象两种方式进行訪问,通过类名改动类变量,该类和全部实例所共享的数据将被改动,再次通过类或实例訪问得到的将是新的数据,这一点与C++是一致的。可是通过实例对象改动类变量,其效果将只作用在该实例上,再次通过类或其他实例訪问得到的仍然是旧的数据。

但这一改动方式将对该类变量实例化。其结果是该实例将得到一个单独的该变量拷贝。此后此对象不再与类共享该名称的变量。

(这一点Python有点复杂),看以下的样例:


class classA:

     classVar = ''

     def __init__(self):

          pass



     def set_var1(self,x):

          classA.classVar= x



     def set_var2(self,y):

          self.var2 = y

          return self.var2





     oa = classA()

     ob = classA()




oa.set_var1("class variable.")

print oa.classVar     #class variable.

print ob.classVar     #class variable.



oa.classVar = "changed."

print oa.classVar     #changed.

print ob.classVar     #class variable.



oa.set_var1("class variable01")

print oa.classVar      #changed.

print ob.classVar      #class variable01





ob.set_var1("class variable02")

print oa.classVar       #changed.

print ob.classVar       #class variable02



ob.set_var2("inst variable")

print ob.var2

#print oa.var2          #error! because var2 is a instance variable


   假设须要在类外改动类属性,必须通过类对象去引用然后进行改动。

假设通过实例对象去引用。会产生一个同名的实例属性。这样的方式改动的是实例属性。不会影响到类属性,而且之后假设通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。


5.普通函数和静态函数:Hello是普通函数,PrintClassNum是静态函数。printClassCount()类似C++的静态函数。就像静态函数没有this指针一样,它也没有self变量。静态函数仅仅能訪问静态成员变量(类变量)。与C++一样。能够使用实例对象和类名来调用静态函数,仅仅能使用实例变量来调用普通函数。

在类外普通函数(实例函数)仅仅能通过实例对象去调用,不能通过其它方式去调用。


6.类函数和静态函数: ClassMethod是一个类方法。拥有一个參数(类对象)。与静态方法使用类似。他们都能够通过类和实例进行调用。都无法訪问实例成员。

类方法能够通过自己的參数cls訪问类成员,而静态方法则不行,能够通过类名间接訪问。staticmethod无需參数,classmethod须要类变量作为參数传递(不是类的实例)。类函数另一个用途就是能够对类属性进行改动。


7.变量訪问属性:C++的面向对象的语法都比較的规范,有公有、私有和保护的数据类型,而python类是没有权限控制的。全部变量都是能够被外部调用,尽管我们能够在变量或者方法的面前加上双下滑线__。表示私有訪问权限,事实上在内部实现上,是将私有变量进行了转化,规则是:_<类名>__<私有变量>。但这个实际上是python的伪私有。仅仅是一种程序猿约定俗称的规定。加了双下划线就表示私有变量。可是假设要在外部调用的话。还是能够调用的。看以下的样例:

class Test:

     count =  0

     def __init__(self,c):

          self.count = c

          self.__name="zhangzhe"     #私有变量

          self.__class__.count = self.__class__.count +1



     def __get_name(self):           #私有方法

          return self.__name



     def get_counte(self):

          return self.count

a = Test(3)

print a.count #3

#print a.name  #AttributeError:Test
instance has no attribute 'name'

print Test.count #1

print a.get_counte() #3



print a.__dict__  #{'count': 3, '_Test__name': 'zhangzhe'}

print a._Test__name  #zhangzhe

print Test.__dict__

#{'count': 1, '__module__': 'classdemo02', '_Test__get_name':
<function __get_name at 0x101e92500>, '__doc__': None, '__init__':
<function __init__ at 0x101e92488>, 'get_counte': <function get_counte at 0x101e92578>}

print a._Test__get_name()   #zhangzhe





b = Test(-1)

print b.count    #1

print Test.count #2

      
 这里定义的__name是私有属性,__get_name()是私有方法,直接訪问的话,会提示找不到相关的属性或者方法。能够通过使用 a._Test__name和a._Test__get_name()来訪问私有的变量和方法。
        注:在Python中没有像C++中public和private这些keyword来差别公有属性和私有属性。它是以属性命名方式来区分,假设在属性名前面加了2个下划线'__'。则表明该属性是私有属性,否则为公有属性

小结:
         对于类属性和实例属性。假设在类方法中引用某个属性。该属性必然是类属性。而假设在实例方法中引用某个属性(不作更改),而且存在同名的类属性。此时若实例对象有该名称的实例属性,则实例属性会屏蔽类属性,即引用的是实例属性。若实例对象没有该名称的实例属性。则引用的是类属性。假设在实例方法更改某个属性,而且存在同名的类属性,此时若实例对象有该名称的实例属性,则改动的是实例属性。若实例对象没有该名称的实例属性,则会创建一个同名称的实例属性。想要改动类属性,假设在类外。能够通过类对象改动,假设在类里面,仅仅有在类方法中进行改动。

  从类方法和实例方法以及静态方法的定义形式就能够看出来,类方法的第一个參数是类对象cls,那么通过cls引用的必然是类对象的属性和方法。而实例方法的第一个參数是实例对象self。那么通过self引用的可能是类属性、也有可能是实例属性(这个须要详细分析)。只是在存在同样名称的类属性和实例属性的情况下。实例属性优先级更高。静态方法中不须要额外定义參数。因此在静态方法中引用类属性的话,必须通过类对象来引用。


        从上面看来,Python是很的灵活 的,它的面向对象没有做到真正的不能訪问,仅仅是一种约定让大家去遵守,就像大家都用self来代表在类里的当前对象,你也能够用其它的,仅仅是大家习惯了用self。


三 类中的内置方法

     除了上面的init和del方法外。Python类中还有例如以下的多个内置方法(类似于C++中的运算符重载):
   


1.__new__():__new__()在__init__()之前被调用。用于生成实例对象。利用这种方法和类属性的特性能够实现设计模式中的单例模式。

单例模式是指创建唯一对象吗,单例模式设计的类仅仅能实例化一个对象。比如以下的代码:

   __instance = None
  def __new__(cls, *args, **kwargs):       #在init函数前被调用

if ZZClass.__instance is None:         #生产唯一实例

            print("ZZClass __new__ called.")

            ZZClass.__instance = object.__new__(cls,*args,**kwargs)

        return ZZClass.__instance

2.__getattr__()、__setattr__()和__getattribute__():当读取对象的某个属性时。python会自己主动调用__getattr__()方法。

比如。fruit.color将转换为fruit.__getattr__(color)。

当使用赋值语句对属性进行设置时,python会自己主动调用__setattr__()方法。__getattribute__()的功能与__getattr__()类似,用于获取属性的值。

可是__getattribute__()能提供更好的控制。代码更健壮。注意,python中并不存在__setattribute__()方法。


3.    __str__()用于表示对象代表的含义。返回一个字符串.实现了__str__()方法后,能够直接使用print语句输出对象,也能够通过函数str()触发__str__()的运行。

这样就把对象和字符串关联起来。便于某些程序的实现。能够用这个字符串来表示某个类。


比如:
def __str__(self):

return  "ZZClass itself."


4. __call__():在类中实现__call__()方法,能够在对象创建时直接返回__call__()的内容。使用该方法能够模拟静态方法。
比如:
  class InternalClass:

        def __call__(self, *args, **kwargs):

            print "internal class."



    func = InternalClass() # 调用InternalClass()。此时将类InternalClass作为函数返回,

                                     # 即为外部类ZZClass定义方法func(),func()将运行__call__()内的代码。

  
   myObj.func()  #internal class.

myObj.func()  #internal
class.


5.__getitem__():假设类把某个属性定义为序列,能够使用__getitem__()输出序列属性中的某个元素。

class Persons:

    def __getitem__(self, item):

        return self.persons[item]



allPersons = Persons()

allPersons.persons = ["Alice","Joe"]

print allPersons[1]

补充:
强类型语言

       一种总是强制类型定义的语言,Java和Python是强制类型定义的,假设你有一个整数。不显示地进行转换。不能将其视为一个字符串。

弱类型定义语言

         一种类型能够被忽略的语言。与强类型定义相反。VBScript是弱类型定义 的。在VBScript中,能够将字符串
'12' 和整数 3 进行连接得到字符串 '123', 然后能够把它看成整数 123。而不须要显示转换。


       注意:强弱类型中心词是‘类型’。而不是变量,一个变量是否可以绑定到多种类型,跟该语言是否强弱类型无关。

动态联编
       
 编译程序在编译阶段并不能确切知道将要调用的函数,仅仅有在程序执行时才干确定将要调用的函数,为此要确切知道该调用的函数,要求联编工作要在程序执行时进行,这样的在程序执行时进行联编工作被称为动态联编。
       事实上它不是 Python 的特性,全部面向对象的语言基本都须要实现。它使得运行一个对象的方法时。使用的是它自己(或它的类)的方法,而不是它的父类的方法。
       动态联编通常的实现方法是把函数的入口地址保存起放在一个表里,(比如。c++的虚表),在执行时通过动态的查找表的方式来推断应该调用哪个函数。函数的执行效率没有静态联编的高,但比其灵活。

 静态联编
        静态联编是指联编工作出如今编译连接阶段,这样的联编又称早期联编。它在编译时就攻克了程序中的操作调用与运行该操作代码间的关系。


Python -面向对象(一 基本概念)的更多相关文章

  1. python面向对象编程 -- 基本概念

    面向对象的编程简要概括就是将要处理的问题抽象为数据和操作的集合,用类对其进行封装.其中数据和操作都称为类的属性,它们是一般是不变的. 对类进行实例化生成我们所说的对象,对象有自己的属性.对象的属性一般 ...

  2. python 面向对象的基本概念(未完待续)

    面向对象编程简称OOP(Object-oriented-programming),是一种程序设计思想. 面向过程编程(如C语言)指一件事该怎么做,面向对象编程(如Java.python)指一件事该让谁 ...

  3. python面向对象编程学习

    python面向对象编程 基本概念理解 面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作 ...

  4. Python 面向对象笔记

    Python 面向对象课程笔记 前言 Python 面向对象 正文 基本概念 什么是对象: 万物皆对象 对象是具体物体: 拥有属性 拥有行为 封装零散为整体 OOP(Object Oriented P ...

  5. python面向对象基本概念(OOP)

    面向对象(OOP)基本概念 面向对象编程 —— Object Oriented Programming 简写 OOP 目标 了解 面向对象 基本概念 01. 面向对象基本概念 我们之前学习的编程方式就 ...

  6. python面向对象编程(1)——基本概念,术语,self,构造器

    1  python面向对象命名规范 类名通常由大写字母打头.这是惯例标准. 数据值应该使用名词作为名字,方法使用动词加对象的方式,若使用混合记法,则方法名的第一个字母首字母小写,后面的单词的首字母大写 ...

  7. 【python】-- 面向对象引子、概念

    面向过程编程 1.编程范式 编程是 程序 员 用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程 , 一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马 ...

  8. python 面向对象初级篇

    Python 面向对象(初级篇) 概述 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发" ...

  9. python 面向对象学习

    ------Python面向对象初 下面写一个类的简单实用,以便方便理解类 #python 3.5环境,解释器在linux需要改变 #阅读手册查询readme文件 #作者:S12-陈金彭 class ...

  10. python 面向对象、特殊方法与多范式、对象的属性及与其他语言的差异

    1.python 面向对象 文章内容摘自:http://www.cnblogs.com/vamei/archive/2012/06/02/2532018.html   1.__init__() 创建对 ...

随机推荐

  1. 关于applicationContext.xml cannot be opened because it does not exist的解决

    初学Spring在用Resource rs=new ClassPathResource("applicationContext.xml");时老是遇到这个错误.后来发现用 Appl ...

  2. [典型漏洞分享]YS VTM模块存在格式化字符串漏洞,可导致VTM进程异常退出【高危】

    YS VTM模块存在格式化字符串漏洞,可导致VTM进程异常退出[高危] 问题描述: YS VTM模块开放对外监听端口(8554和8664),此次使用sulley fuzzing框架对监听在8664端口 ...

  3. es6,async简单总结

    1.简单来讲就是把函数变为异步操作的 async function demo() { let result = Math.random(); console.log(result); } 2.asyn ...

  4. [Linux] Proc 文件系统

    转载自:http://linux.chinaunix.net/doc/2004-10-05/16.shtml#324lfindex0 目录: /proc --- 一个虚拟文件系统 加载 proc 文件 ...

  5. Kubernetes Pod日志太大导致空间问题

    在log-driver是json-file的模式下,容器的日志存放在/var/lib/docker/containers/下面,是以container_id-json.log文件存放 但缺省方式下,l ...

  6. 《Go语言实战》笔记之第四章 ----数组、切片、映射

    原文地址: http://www.niu12.com/article/11 ####数组 数组是一个长度固定的数据类型,用于存储一段具有相同的类型的元素的连续块. 数组存储的类型可以是内置类型,如整型 ...

  7. synchronized 线程同步

    synchronized  通常用来形容一次方法的调用,调用一旦开始,调用者必须等到方法调用返回后,才能继续执行后续的操作. 1.demo package demo1; public class My ...

  8. 用phonegap和jquery-mobile写android应用

    今天纪录的是学习用phonegap和jquery-moblie来写android的过程.环境搭建. 我的习惯是直接上官网看文档,看get-started guide之类的文档.然后在看参考手册.然后就 ...

  9. [转]sa不能远程连接sql server 2008的解决办法

    本文转自:http://www.cnblogs.com/chendaoyin/archive/2012/08/25/2656900.html 方法: 开始->Microsoft SQL Serv ...

  10. linux下安装oracle需要的配置

    1.检查系统包安装情况 rpm -qa|grep binutils rpm -ivh sysstat-7.0.2.rpm rpm -ivh binutils-2.17.50.0.6-14.el5.*. ...