关键字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()