Python基础进阶篇——面向对象编程基础

本文详细介绍了Python中类与实例的概念,包括实例属性的排序、初始化、访问限制、类属性的创建与使用、实例方法与类方法的定义及动态添加方法等内容。

关键字class相信大家都很熟悉,在后端语言中,一个class代表一个类,对这个类进行调用就是实例;
打个比方:
人——>类,
张三——>实例
下面贴出代码和注释讲解本文内容:

#-*- coding: utf-8 -*-

# 实例的name属性的排序
class Person(object):
    pass

p1 = Person()
p1.name ='Bart'

p2 = Person()
p2.name = 'Adam'

p3 = Person()
p3.name = 'Lisa'

L1 = [p1,p2,p3]
L2 = sorted(L1, lambda p1,p2:cmp(p1.name, p2.name))

print L2
print L2[0].name
print L2[1].name
print L2[2].name

# python中初始化实例属性
# __init__方法,除了接受name、gender、birth等属性外,还可以接受关键字参数,并把
# 他们都作为属性赋值给实例;
class SpecialPerson(object):
    def __init__(self, name, gender, birth, **kw):
        self.name = name;
        self.gender = gender;
        self.birth = birth;
        print kw # {"job":"sutdent", "location":"panjin"}
        for k,v in kw.iteritems():
            setattr(self, k, v)


xiaoming = SpecialPerson('XiaoMing','Male','1990-1-1',job='student',location='panjin')

print xiaoming.name
print xiaoming.job
print xiaoming.location

# python中访问限制
# 我们可以给一个实例很多属性,如果有些属性不希望不外部访问到,这个属性就以
# 双下划线"__"开头,该属性就无法被外部访问到;
# 但是,如果一个属性以"__xxx__"的形式定义,那它又可以被外部访问了,以"__xxx__"
# 形式定义的属性在python中被称为:特殊属性,有很多预定义的特殊属性可以用,通常
# 我们不要把普通属性用"__xxx__"定义。

class RestrictPerson(object):
    """docstring for RestrictPerson"""
    def __init__(self, name, score):
        self.name = name;
        self.__score = score;

p = RestrictPerson('xiaohong',59)

print p.name
# print p.score 会报错,打印不出来的,因为外部访问不到;

# python中创建类属性
# 类是模板,而实例则是根据类创建的对象
# 实例的属性每个实例各自拥有,互相独立,而类的属性有且只有一份
# 定义类属性可以直接在class中定义:
class AttrPerson(object):
    """docstring for AttrPerson"""
    adress = 'Earth'
    def __init__(self, name):
        self.name = name
# 因为类属性是直接绑定在类上的,所以不需要实例就可以直接访问:

print AttrPerson.adress # Earth

# 对于实例调用类的属性也是可以访问的,所有实例都可以访问到它所属类的属性:

p1 = AttrPerson('tong')
p2 = AttrPerson('guoli')

print p1.name
print p1.adress
print p2.name
print p2.adress

# 因为python是动态语言,所以类的属性也是可以修改的
AttrPerson.adress = 'China'
print p1.adress # China
print p2.adress # China
# 因为类属性只有一份,所以,当AttrPerson类的属性adress改变时,所有实例访问到的类属性都改变了。

class Number(object):
    """docstring for Number"""
    count = 0
    def __init__(self, name):
        Number.count = Number.count+1
        self.name = name

n1 = Number('tong')
n2 = Number('shuo')
n3 = Number('he')
n4 = Number('guoli')
print Number.count      

# 如果类属性和实例属性名字冲突怎么办
class DelAttrbute(object):
    """docstring for DelAttrbute"""
    adress = 'Earth'
    def __init__(self, name):
        self.name = name

p1 = DelAttrbute('tong')
p2 = DelAttrbute('shuo')

print DelAttrbute.adress # Earth
p1.adress = 'China'
print p1.adress # China
print p2.adress # Earth

# 可见在实例上修改类属性是不生效的,而是在实例上重新创建了一个属性adress
# 当实例属性和类属性同名的时候
# 首先查找到的是实例属性,也就是实例属性优先级高
class Number(object):
    """docstring for Number"""
    __count = 0
    def __init__(self, name):
        Number.__count = Number.__count+1
        self.name = name

n1 = Number('tong')
n2 = Number('suo')

# print Number.__count # 会报错,以为__count是Number的私有属性,在外部访问不到

# python中定义实例方法
class PersonSet(object):
    """docstring for PersonSet"""
    def __init__(self, name):
        self.__name = name

    def get_name(self):
        return self.__name
        pass

ps1 = PersonSet("hello word")
print ps1.get_name # 返回一个函数对象
print ps1.get_name() # 对返回这个函数对象进行调用得到结果

# 通过实例方法可以访问内部属性值;

class PersonSocre(object):
    """docstring for PersonSocre"""
    def __init__(self, name, score):
        self.name = name
        self.__score = score
    def get_grade(self):
        if self.__score >= 80:
            return 'A'
        if self.__score >= 60:
            return 'B'
        return 'C'

p1 = PersonSocre('Bob',90)
p2 = PersonSocre('Alice',65)
p3 = PersonSocre('Tim', 59)

print p1.get_grade()
print p2.get_grade()
print p3.get_grade()

# 方法也是属性,上面这个类中定义的函数(方法)也属于属性;
# 因为函数(方法)也是属性,所以他可以动态的添加到实例上,只是需要用
# types.MethodType()把一个函数变为方法,当然需要引进types模块
import types
def fn_get_grade(self):
    if self.score >= 80:
        return "A"
    if self.score >= 60:
        return "B"
    return "C"
    pass

class PersonSocreNew(object):
    """docstring for PersonSocreNew"""
    def __init__(self, name, score):
        self.name = name
        self.score = score

p1 = PersonSocreNew('tongshuo',99)
p1.get_grade = types.MethodType(fn_get_grade,p1,PersonSocreNew)
print p1.get_grade()
p2 = PersonSocreNew('guoli',59)
# print p2.get_grade() # 会报错,因为p2实例并没有绑定get_grade属性
# 给一个实例动态添加方法并不常见,直接在class中定义要更直观;


# python中定义类方法
class School(object):
    """docstring for School"""
    count = 0
    @classmethod
    def how_many_students(cls):
        return cls.count
        pass
    def __init__(self, name):
        self.name = name
        School.count = School.count+1

print School.how_many_students() # 0
p1 = School('tongshuo')
print School.how_many_students() # 1
# 通过标记一个@classmethod,该方法将绑定到Person类上,而非类的实例,类方法的第一个参数将传入类本身,通常将参数名命名为cls,上面的cls.count实际上相当于School.count.
# 因为是在类上调用,而非实例上调用,因此类方法无法获得任何实例变量,只能获得类的引用。

# 同样类的私有属性,也可以在外部通过类方法访问:
class SchoolNew(object):
    __count = 0
    @classmethod
    def how_many_students(cls):
        return cls.__count
        pass
    def __init__(self, name):
        self.name = name
        SchoolNew.__count = SchoolNew.__count + 1

print SchoolNew.how_many_students()
s1 = SchoolNew('tongshuo')
print SchoolNew.how_many_students()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值