面向对象编程

1、即便是整数也被作为对象(属于int类)。


2、Python中的self等价于C++中的self指针和Java、C#中的this参考。


3、创建类

# Filename: simplestclass.py

class Person:
    pass # An empty block

p = Person()
print p

输出

$ python simplestclass.py
<__main__.Person instance at 0xf6fcb18c>

使用class语句后跟类名,创建了一个新的类,这后面跟着一个缩进的语句块形成类体。在这个例子中,我们使用了一个空白块,它由pass语句表示。

接下来,使用类名后跟一对圆括号来创建一个对象/实例。简单地打印了这个变量的类型,它告诉我们我们已经在__main__模块中有了一个Person类的实例。


4、对象方法

类/对象可以拥有像函数一样的方法,这些方法与函数的区别只是一个额外的self变量。

# Filename: method.py

class Person:
    def sayHi(self):
        print 'Hello, how are you?'

p = Person()
p.sayHi()


Person.sayHi(p)

输出

$ python method.py

Hello, how are you?
Hello, how are you?

注意 sayHi 方法没有任何参数,但仍然在函数定义时有 self


5、__init__方法

__init__方法在类的一个对象被建立时,马上运行,这个方法可以用来对对象做一些 初始化 。注意,这个名称的开始和结尾都是双下划线。

# Filename: class_init.py

class Person:
    def __init__(self, name):
        self.name = name

    def sayHi(self):
        print 'Hello, my name is', self.name

p = Person('Swaroop')
p.sayHi()


# This short example can also be written as Person('Swaroop').sayHi()

输出

$ python class_init.py
Hello, my name is Swaroop

最重要的是,并没有专门调用 __init__ 方法,只是在创建一个类的新实例的时候,把参数包括在圆括号内跟在类名后面,从而传递给 __init__ 方法。这是这种方法的重要之处。

__init__方法类似于C++、C#和Java中的 constructor 。


6、类变量和对象变量

类的变量 由一个类的所有对象(实例)共享使用。只有一个类变量的拷贝,所以当某个对象对类的变量做了改动的时候,这个改动会反映到所有其他的实例上。

对象的变量 由类的每个对象/实例拥有。因此每个对象有自己对这个域的一份拷贝,即它们不是共享的,在同一个类的不同实例中,虽然对象的变量有相同的名称,但是是互不相关的。

# Filename: objvar.py

class Person:
    '''Represents a person.'''
    population = 0

    def __init__(self, name):
        '''Initializes the person's data.'''
        self.name = name
        print '(Initializing %s)' % self.name

        # When this person is created, he/she
        # adds to the population

        Person.population += 1

    def __del__(self):
        '''I am dying.'''
        print '%s says bye.' % self.name

        Person.population -= 1

        if Person.population == 0:
            print 'I am the last one.'
        else:
            print 'There are still %d people left.' % Person.population

    def sayHi(self):
        '''Greeting by the person.

        Really, that's all it does.'''

        print 'Hi, my name is %s.' % self.name

    def howMany(self):
        '''Prints the current population.'''
        if Person.population == 1:
            print 'I am the only person here.'
        else:
            print 'We have %d persons here.' % Person.population

swaroop = Person('Swaroop')
swaroop.sayHi()
swaroop.howMany()

kalam = Person(
'Abdul Kalam')
kalam.sayHi()
kalam.howMany()

swaroop.sayHi()
swaroop.howMany()

输出

$ python objvar.py
(Initializing Swaroop)
Hi, my name is Swaroop.
I am the only person here.
(Initializing Abdul Kalam)
Hi, my name is Abdul Kalam.
We have 2 persons here.
Hi, my name is Swaroop.
We have 2 persons here.
Abdul Kalam says bye.
There are still 1 people left.
Swaroop says bye.
I am the last one.

population 属于 Person 类,因此是一个类的变量。 name 变量属于对象(它使用 self 赋值)因此是对象的变量。

可以在运行时使用Person.__doc__Person.sayHi.__doc__来分别访问类与方法的文档字符串。

一个特殊的方法__del__,它在对象消逝的时候被调用。对象消逝即对象不再被使用,它所占用的内存将返回给系统作它用。在这个方法里面,我们只是简单地把Person.population1

当对象不再被使用时,__del__方法运行,但是很难保证这个方法究竟在 什么时候 运行。如果你想要指明它的运行,你就得使用del语句,就如同我们在以前的例子中使用的那样。

注意
Python中所有的类成员(包括数据成员)都是 公共的 ,所有的方法都是 有效的 。
只有一个例外:如果你使用的数据成员名称以 双下划线前缀 比如__privatevar,Python的名称管理体系会有效地把它作为私有变量。
这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单下划线前缀。而其他的名称都将作为公共的,可以被其他类/对象使用。记住这只是一个惯例,并不是Python所要求的(与双下划线前缀不同)。
同样,注意__del__方法与 destructor 的概念类似。


7、继承

一个子类型在任何需要父类型的场合可以被替换成父类型,即对象可以被视作是父类的实例,这种现象被称为多态现象

# Filename: inherit.py

class SchoolMember:
    '''Represents any school member.'''
    def __init__(self, name, age):
        self.name = name
        self.age = age

        print '(Initialized SchoolMember: %s)' % self.name

    def tell(self):
        '''Tell my details.'''
        print 'Name:"%s" Age:"%s"' % (self.name, self.age),

class Teacher(SchoolMember):
    '''Represents a teacher.'''
    def __init__(self, name, age, salary):
        SchoolMember.__init__(self, name, age)
        self.salary = salary

        print '(Initialized Teacher: %s)' % self.name

    def tell(self):
        SchoolMember.tell(self)

        print 'Salary: "%d"' % self.salary

class Student(SchoolMember):
    '''Represents a student.'''
    def __init__(self, name, age, marks):
        SchoolMember.__init__(self, name, age)
        self.marks = marks

        print '(Initialized Student: %s)' % self.name

    def tell(self):
        SchoolMember.tell(self)

        print 'Marks: "%d"' % self.marks

t = Teacher(
'Mrs. Shrividya'4030000)
s = Student(
'Swaroop'2275)

print # prints a blank line

members = [t, s]
for member in members:
    member.tell() 
# works for both Teachers and Students

输出

$ python inherit.py
(Initialized SchoolMember: Mrs. Shrividya)
(Initialized Teacher: Mrs. Shrividya)
(Initialized SchoolMember: Swaroop)
(Initialized Student: Swaroop)

Name:"Mrs. Shrividya" Age:"40" Salary: "30000"
Name:"Swaroop" Age:"22" Marks: "75"

为了使用继承,把基本类的名称作为一个元组跟在定义类时的类名称之后。然后,注意到基本类的__init__方法专门使用self变量调用,这样就可以初始化对象的基本类部分。这一点十分重要——Python不会自动调用基本类的constructor,得亲自专门调用它。还观察到在方法调用之前加上类名称前缀,然后把self变量及其他参数传递给它。

在这个例子中,调用了子类型的tell方法,而不是SchoolMember类的tell方法。可以这样来理解,Python总是首先查找对应类型的方法,在这个例子中就是如此。如果它不能在导出类中找到对应的方法,它才开始到基本类中逐个查找。基本类是在类定义的时候,在元组之中指明的。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值