1.定义一个类
1.1老式类与新式类:
1.2两个内建函数:
1.2.1对比代码:
输出两个类的属性和类型
1.2.2结果:
2.定义类的属性
2.1直接在类里定义:
2.2在构造函数里定义:
3.访问控制:
用最后一个输出语句可以访问双下滑线的所谓的私有属性
双下滑线的属性,python会把它的名字改一下而已,并没有进行真正的进行访问控制
4.定义类的方法
在python中一切皆对象
类的方法也是类的属性
4.1方法的访问控制
4.2特殊的装饰器
4.2.1一个例子
5.类的继承
5.1定义类的继承
class DerivedClassName(BaseClassName):
<statement-1>
·
·
·
<staement-N>
5.1.1继承的子类:
- 会继承父类的属性和方法
- 也可以自己定义,覆盖父类的属性和方法
5.1.2用super()调用父类的方法
class A(object):
def method(self,arg):
pass
class B(A):
def method(self, arg):
super(B, self).method(arg)
或者直接调用,但这样体现不出来继承
class A(object):
def method(self, arg):
pass
class B(A):
def method(self, arg):
A.method(arg)
5.1.3子类的类型判断
两个方法
- isinstance - 判断类型
- issubclass - 判断是否是子类
5.2多继承
class DerivedClassName(Base1, Base2, Base3):
<statement-1>
·
·
·
<statement-N>
5.3实例代码
#coding:utf-8
class Programer(object):# 定义了一个父类
hobby = 'Play Computer'
def __init__(self, name, age, weight):
self.name = name
self._age = age
self.__weight = weight
@classmethod
def get_hobby(cls):
return cls.hobby
@property
def get_weight(self):
return self.__weight
def self_introduction(self):
print 'My Name is %s \nI am %s years old\n' % (self.name, self._age)
class BackendProgramer(Programer):# 定义子类继承父类
def __init__(self, name, age, weight, language):
super(BackendProgramer, self).__init__(name, age, weight)
self.language = language
if __name__ == '__main__':
programer = BackendProgramer('Albert', 25, 80, 'Python')
print dir(programer)# 打印对象的属性
print programer.__dict__
print type(programer)# 打印对象的类型
print isinstance(programer, Programer)# 判断programer是否为Programer的子类
运行结果:
['_Programer__weight', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_age', 'hobby', 'language', 'name']
{'_age': 25, '_Programer__weight': 80, 'name': 'Albert', 'language': 'Python'}
<class '__main__.BackendProgramer'>
True
6.类的多态
6.1多态的要素
- 继承
- 方法重写
6.2实例代码
# coding:utf-8
class Programer(object):
hobby = 'Play Computer'
def __init__(self, name, age, weight): # 构造方法
self.name = name
self._age = age
self.__weight = weight
@classmethod
def get_hobby(cls):
return cls.hobby
@property
def get_weight(self):
return self.__weight
def self_introduction(self):
print 'My Name is %s \nI am %s years old\n' % (self.name, self._age)
class BackendProgramer(Programer):
def __init__(self, name, age, weight, language):
super(BackendProgramer, self).__init__(name, age, weight)
self.language = language
def self_introduction(self):
print 'My name is %s \nMy favorite language is %s' % (self.name, self.language)
def introduce(programer):
if isinstance(programer, Programer):
programer.self_introduction()
if __name__ == '__main__':
programer = Programer('Albert', 25, 80,)
backend_programer = BackendProgramer('Tim', 30, 70, 'Python')
introduce(programer)
introduce(backend_programer)
结果:
My Name is Albert
I am 25 years old
My name is Tim
My favorite language is Python
7.Magic Method
7.1Magic Method 长什么样
方法名的前后有两个下划线
def __init__(self):
7.2对象实例化的过程
创建类的对象 ---> 初始化对象
def __new__(cls) def __init__(self):
# coding:utf-8
class Programer(object):
hobby = 'Play Computer'
def __new__(cls, *args, **kwargs):
print 'call __new__ method'
print args
return super(Programer, cls).__new__(cls, *args, **kwargs)
def __init__(self, name, age): # 构造方法 # 这个注释距离代码两格#号距离注释一格
print 'call __init__ method'
self.name = name
self._age = age
if __name__ == '__main__':
programer = Programer('Albert', 25)
print programer.__dict__
结果:
call __new__ method
('Albert', 25)
call __init__ method
{'_age': 25, 'name': 'Albert'}
7.2.1回收
__del__()
8.类与运算符
>>> s == 'test'
>>> s== s
True
>>>dir(s)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__' ...]
比较运算符
__cmp__(self, other) # 所有比较
__eq__(self, other) # 等于
__lt__(self, other) # 小于
__gt__(self, other) # 大于
__add__(self, other) # 加
__sub__(self, other) # 减
__mul__(self, other) # 乘
__div__(self, other) # 除
逻辑运算符
__or__(self, other) # 或
__and__(self, other) # 和
例子:
# coding:utf-8
class Programer(object):
def __init__(self, name, age): # 构造方法
self.name = name
if isinstance(age, int):
self.age = age
else:
raise Exception('age must be int')
def __eq__(self, other):
if isinstance(other, Programer):
if self.age == other.age:
return True
else:
return False
else:
raise Exception('The type of object must be Programer')
def __add__(self, other):
if isinstance(other, Programer):
return self.age + other.age
else:
raise Exception('The type of object must be Programer')
if __name__ == '__main__':
p1 = Programer('Albert', 25)
p2 = Programer('Bill', 30)
print p1 == p2
print p1 + p2
结果:
False
55
9.类的展现
转换为字符串
__str__ -- 把对象转换成人容易看的字符串
__repr__ -- 把对象转换成机器容易看的字符串
__unicode__
例子:
# coding:utf-8
class Programer(object):
def __init__(self, name, age): # 构造方法
self.name = name
if isinstance(age, int):
self.age = age
else:
raise Exception('age must be int')
def __str__(self):
return '%s is %s years old' % (self.name, self.age)
def __dir__(self):
return self.__dict__.keys()
if __name__ == '__main__':
p = Programer('Albert', 25)
print p
print dir(p)
结果:
Albert is 25 years old
['age', 'name']
可以通过魔术方法给属性设置访问控制
__setattr__(self, name, value):
错误示范:
def __setattr__(self, name, value):
setattr(self, name, value) # 无限循环
def __setattr__(self, name, value):
self.__dict__[name] = value # 正确用法
查询对象属性
__getattr__(self, name);
__getattribute__(self, name):
删除对象属性
__delattr__(self, name):
例子:
# coding:utf-8
class Programer(object):
def __init__(self, name, age): # 构造方法
self.name = name
self.age = age
def __getattribute__(self, name):
# return getattr(self, name) # 无限循环
# return self.__dict__[name] # 无限循环
return super(Programer, self).__getattribute__(name) # 正确写法
def __setattr__(self, name, value):
# setattr(self, name, value) # 无限循环
self.__dict__[name] = value # 正确写法
if __name__ == '__main__':
p = Programer('Albert', 25)
print p.name