
定义类class Person():pass创建实例xiaoming Person()xiaohong Person()实例属性xiaoming Person()xiaoming.name xiaomingxiaoming.age 24xiaoming.sex manxiaohong Person()xiaohong.name xiaohongxiaohong.age 22xiaohong.sex woman初始化实例属性这个情况是当一个实例在进行创建的动作的时候, 会自动地被去调用一个方法。class Person(object):def __init__(self, name, age, sex):self.name nameself.age ageself.sex sex属性的访问限制在中定义了普通变量, 这些变量是可以被外部直接进行访问的, 不过有时候我们所定义的变量是不希望被外面给访问到的。对于属性权限的控制这个事儿, 咱们是通过属性名来搞定的。要是有一个属性, 它是由两个下划线也就是那个双下划线__开头的, 那这个属性就别想被在外面直接访问到了。可是, 假如外面确实想要去访问这么一种变量呢? 那你可以通过调用实例方法的方法来弄到它。至于说具体是怎么个弄法, 在后头会有详细的介绍。class Person(object):def __init__(self, name):self.name nameself._title Mrself.__job Studentp Person(Bob)print p.name # Bobprint p._title # Mrprint p.__job# ErrorTraceback (most recent call last):File , line 1, inAttributeError: Person object has no attribute __job这种属性是用这样的形式来进行定义的, 所以说它是允许进行外部访问的。在相关的环境里面把它叫做特殊属性。平常的情况来看, 它多半是那种已经内置好的属性或者是已经内置好的方法, 所以在我们自己去定义属性和定义方法的时候, 一般都不建议采用这种形式来做。类属性所谓类属性, 实际上就是指那些被直接创建在类内部的属性。每个实例都各自拥有自己的独立属性, 彼此之间互不干扰而类数据属性仅仅只存在一份, 所有被创建出来的实例对象都会去从那个唯一的类属性里面进行继承。换句话说来说, 也就是说是绑定到某一个特定实例上面的数据属性, 不会对其他的任何实例产生哪怕一丁点的影响。如果说是在类的层面对其绑定一个属性, 那么情况下所有的实例对象都可以去访问到这个类级别的属性, 并且所访问到的类数据属性确实是同一个东西, 一旦这个类数据属性的数值发生变动, 就会立刻波及并影响到所有的其他实例。class Person(object):address Earth # 类属性addressdef __init__(self, name):self.name nameprint Person.address # Earth 类属性直接绑定在类上的可以不实例化直接通过类名调用类属性p1 Person(Bob)p2 Person(Alice)print p1.address # Earth # 通过实例来调用类属性print p2.address # Earth请把类属性 count 添加到该类别中, 每一次去创建一个实例的时候, 就让这个 count 属性去加 1, 这样一来, 就可以统计出到底一共创造出了多少个这样的类的实列了。class Person(object):count0count 1def __init__(self, name):self.name namep1 Person(Bob)print Person.count # 1p2 Person(Alice)print Person.count # 1p3 Person(Tim)print Person.count # 1上述的那些代码, 它们并没有达到人们心中所想的那种想要达到的效果方面去。class Person(object):count0def __init__(self, name):self.name namePerson.count 1p1 Person(Bob)print Person.count # 1p2 Person(Alice)print Person.count # 2p3 Person(Tim)print Person.count # 3把它想象成一个构造函数, 那个在构造函数外面写的count等于0, 就可以被理解成一个默认的参数。当去创建对象实例的时候, 最先被执行的是构造函数。由于在这个时候调用函数里面的count变量没有具体的值, 所以系统就会去使用前面说的那个默认参数。因此, 第一次进行调用的时候, count拿到的就是零这个默认的值等到了第二回再去调用的时候, 因为是用带有参数的形式进行的调用, 所以这里使用的就变成是那个有参数的count了。count等于0这个动作, 是对最开始的那一次进行的赋值操作, 它只会发生一次, 然后往后面的每一个对象在使用的过程中, 都会去使用已经被修改过的那个count值。当实例属性跟类属性的名称一模一样的时候, 会出现重名的状况。在实际情况里, 当实例属性和类属性的名字是重复的, 那么实例属性的优先级就是更高一点了, 它会把对类属性进行的访问给屏蔽掉。class Person(object):address zhejiangdef __init__(self, name):self.name namep1 Person(Bob)p2 Person(Alice)print Person.address Person.address # zhejiangp1.address shanxiprint p1.address p1.address # shanxiprint Person.address Person.address # zhejiangprint p2.address p2.address # zhejiang由此可见, 大家一定要注意的是, 绝对不要在实例上面去对类属性进行所谓的修改操作因为通过这种方式进行的动作, 实际上它并没有改变那个类属性本身的情况, 反而它只是给当前的这个具体实例额外地绑定上了一个新的、专门属于该实例的属性而已。把实例方法给定义出来。在这个使用场景里, 某一个实例的私有属性是通过“__属性名”这个方式来进行定义的, 因此它不能在外部被直接访问到。不过, 我们可以从类的内部通过间接的手段去访问这些属性, 具体的做法就是借助于实例方法来达到访问的目的。所谓的实例方法, 其实就是那种在类的内部被定义完成的函数, 而在它的那些参数列表里头, 排在第一个位置的参数, 那个名字叫做self的东西, 是专门用来指向那个正在调用这个方法的实例自身的。class Person(object):def __init__(self, name):self.__name namedef get_name(self):return self.__name这个内容其实就是一个实例方法, 而关于调用实例方法这件事必须要在具体的实例上面来执行调用的操作。p1 Person(xiaoming)p1.get_name() # xiaoming在实例方法内部的情况下, 所有实例属性都是可以被访问到的, 如果外部的地方需要去访问私有属性这个情况, 是可以通过方法来调用从而获得这些内容的。类方法在 class 里面被定义的东西, 全部都是属于实例的方法, 这些实例方法的第一个参数叫做 self, 那个 self 代表的就是实例本身。class Person(object):count 0classmethoddef how_many(cls):return cls.countdef __init__(self, name):self.name namePerson.count Person.count 1print Person.how_many()p1 Person(Bob)print Person.how_many()classmethoddef how_many(cls):return cls.countdef __init__(self, name):self.name namePerson.count Person.count 1print Person.how_many()p1 Person(Bob)print Person.how_many()该方法通过一个符号来进行标记, 于是它就被绑定到了类上面去, 而不是类的实例上面。在类方法这个地方, 第一个参数是传入类本身, 所以上面写的cls.count其实就和.count是等同的。因为是在类上去调用这个方法的, 不是在实例上去调用的, 所以类方法没有办法获得任何有关实例里面的变量, 这种情况下只能获取得到类的引用而已。类方法是通过类来直接调用的, 或者是通过实例来直接调用的。class ClassA(object):classmethoddef func_a(cls):print(type(cls), cls)if __name__ __main__:ClassA.func_a()ca ClassA()ca.func_a()