对象
class Father(object):
def __init__(self, name, age):
self.__privateFatherAge = age;
self.publicFatherName = name;
#定义共有属性和私有属性
__privateFatherAge = 44;
publicFatherName = 'feige';
#私有方法访问共有属性
def __privateMethod(self):
print('the name of father is:'+self.publicFatherName);
#共有方法访问私有属性
def publicMethod(self):
print('the age of father is :'+str(self.__privateFatherAge));
#可以通过类名点的形式调用
@classmethod
def aaa(cls):
print('aaaa');
#可以通过对象点的形式调用
@property
def bbb(self):
print('bbbb');
f = Father('fei', 24);
print(f.publicFatherName);
#结果:fei
#print(f.__privateAge);出错
print(f._Father__privateFatherAge);
#结果:24
f.publicMethod();
#结果:the age of father is :24
#f.__privateMethod();出错
f._Father__privateMethod();
#结果:the name of father is:fei
#f2 = Father();出错
Father.aaa();
#结果:aaaa
f.bbb;
#结果:bbbb
总结
Python 在编译的时候动了手脚,所以访问私有属性或者私有方法会报错,只要你按照特殊的形式,就可以访问它们了。
Python 目前的私有机制是虚伪私有,Python 的类是没有权限控制的,所有的变量都是可以被外部访问的。
继承
class Boy(Father):
def __init__(self, sex):
super().__init__('qiang', 18);
self.sex = sex;
class Girl(Father):
def __init__(self, sex):
super().__init__('sheng', 23);
self.sex = sex;
b = Boy('NAN');
g = Girl('NV')
print(b.publicFatherName);
#结果:qiang
print(g.publicFatherName);
#结果:sheng
b.publicMethod();
#结果:the age of father is :18
g.publicMethod();
#结果:the age of father is :23
总结
1、Python 支持多继承,这可能造成代码混乱。
2、可以重写父类的方法。
3、可以定义多个重名的方法,参数列表不一样即可。
4、类方法参数第一个默认为 self。
5、子类不可以继承父类的私有方法和私有属性,但可以通过父类共有方法去访问父类私有属性。
6、调用规则:子类有,用子类的;子类没有,用父类的;父类没有,就报错。
内置函数
issubclass(childClass, parentClass) 判断两个类的关系。
1、注意两个参数是类对象,而不是实例对象。
2、如果 childClass 是 parentClass 的子类或者是子类的子类,则返回 True,否则返回 False。
3、parentClass 可以是一个包含多个类对象的元组。
4、其他情况下可能抛出 TypeError 异常。
print(issubclass(Boy, Father));
#结果:True
isinstance(childobject, childClass) 判断实例与类的关系。
1、第一个参数是实例对象,第二个参数是类对象。
2、如果 childobject 是 childClass 的实例,或者是 childClass 的子类实例,返回 True,否则返回 False。
3、如果第一个参数不是实例对象,永远返回 False。
4、如果第二个参数不是类对象或者多个类对象的元组,会抛出 TypeError 异常。
print(isinstance(b, Father));
#结果:True
hasattr(object, name) 测试一个实例里面是否有某个属性。
print(hasattr(b, 'sex'));
#结果:True
getattr(object, name[, defalt]) 返回对象指定的属性值,没有默认值则抛出 AttributeError 异常。
print(getattr(b, 'sex'));
#结果:NAN
print(getattr(b, 'other', '666'));
#结果:666
setattr(object, name, value) 给一个对象设置属性值。
print(getattr(b, 'sex'));
#结果:NAN
setattr(b, 'sex', 'NV');
print(getattr(b, 'sex'));
#结果:NV
delattr(object, name) 删除对象的某一属性。
print(getattr(b, 'sex'));
delattr(b, 'sex');
print(getattr(b, 'sex'));
#报错:AttributeError: 'Boy' object has no attribute 'sex'
property(fget=None, fset=None, fdel=None, doc=None) 通过属性设置属性。
俗话说:条条大路通罗马,同样是一件事,Python提供了好几种方式供你选择,看下面例子。
class Boy(Father):
def __init__(self, sex):
super().__init__('qiang', 18);
self.sex = sex;
def setSex(slef, value):
slef.sex = value;
def getSex(self):
return self.sex;
def delSex(slef):
del self.sex;
x = property(getSex, setSex, delSex);
#初始化
b = Boy('NAN');
print(b.x);
#结果:NAN
#修改
b.x = 'middle';
print(b.sex);
#结果:middle
#删除
del b.sex;
print(b.sex);
#结果:报错
总结:
如果你某天心血来潮,想对程序进行大改,就可能把 sex 修改成 Usex,这就会导致修改用户的调用接口。
使用 property 方法就完美克服了这个缺点,你只需要修改 Child 这个类就可以完成了。