python 面向对象
在Python中,类通过 class 关键字定义。以 Person 为例,定义一个Person类如下:
class Person():
pass
按照 Python 的编程习惯,类名以大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的。类的继承将在后面的章节讲解,现在我们只需要简单地从object类继承。
有了Person类的定义,就可以创建出具体的xiaoming、xiaohong等实例。创建实例使用 类名+(),类似函数调用的形式创建:
xiaoming = Person()
xiaohong = Person()
没有继承 object 的为传统 classic class,
在py 2.7.11进行了测试
>>> class A(object):
... pass
...
>>> print(type(A))
<type 'type'>
>>> class B():
... pass
...
>>> print(type(B))
<type 'classobj'>
# 可见2个type是不同的
>>> print dir(A)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> print dir(B)
['__doc__', '__module__']
# 属性也是不一样的
而py 3.5.2:
class A(object):
pass
print(type(A))
print(dir(A))
class B():
pass
print(type(B))
print(dir(B))
<class 'type'>
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
<class 'type'>
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
说明 py 3.5 object 已经作为默认基类被继承了(跟 java 一样). 字段 : 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同 。 普通字段属于 对象 , 静态字段属于 类 . class Province:
# 静态字段
country = '中国'
def __init__(self, name):
# 普通字段
self.name = name
# 直接访问普通字段
obj = Province('河北省')
print(obj.name)
# 直接访问静态字段
print(Province.country)
类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
静态方法:由类调用;无默认参数; #!/usr/bin/env python
# Version = 3.5.2
# __auth__ = '无名小妖'
class Foo:
def __init__(self, name):
self.name = name
def ord_func(self):
""" 定义普通方法,至少有一个self参数 """
print('普通方法')
@classmethod
def class_func(cls):
""" 定义类方法,至少有一个cls参数 """
print('类方法')
@staticmethod
def static_func():
""" 定义静态方法 ,无默认参数"""
print('静态方法')
# 调用普通方法
f = Foo('那么')
f.ord_func()
# 调用类方法
Foo.class_func()
# 调用静态方法
Foo.static_func()
def func(self):
pass
# 定义属性
@property
def prop(self):
print('xxx')
# ############### 调用 ###############
foo_obj = Foo()
foo_obj.func()
foo_obj.prop #调用属性
#!/usr/bin/env python
# Version = 3.5.2
# __auth__ = '无名小妖'
class Pager():
def __init__(self,all_count):
self.all_count = all_count
@property
def all_pager(self):
a1,a2 = divmod(self.all_count,10)
if a2 == 0:
x = a1
else:
x = a1 + 1
return x
@all_pager.setter
def all_pager(self,value):
self.all_count = value * 10
@all_pager.deleter
def all_pager(self):
print('deleter') p = Pager(101) print(p.all_pager) # 自动执行 @property 修饰的 all_pager方法,并获取方法的返回值
p.all_pager = 123 # 自动执行 @all_pager.setter 修饰的 all_pager方法,并将 123 赋值给方法的参数
del p.all_pager # 自动执行 @all_pager.deleter 修饰的 price 方法 11
123
deleter 继承: 即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是 模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。 实例化: 创建一个类的实例,类的具体对象。 方法: 类中定义的函数。 对象: 通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
什么是面向对象编程?
面向对象编程是一种程序设计范式
对现实世界建立对象模型
把程序看作不同对象的相互调用
Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。下面我们将详细介绍Python的面向对象编程。
如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对象编程。
接下来我们先来简单的了解下面向对象的一些基本特征。
面向对象技术简介 类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
定义类并创建实例在Python中,类通过 class 关键字定义。以 Person 为例,定义一个Person类如下:
class Person():
pass
按照 Python 的编程习惯,类名以大写字母开头,紧接着是(object),表示该类是从哪个类继承下来的。类的继承将在后面的章节讲解,现在我们只需要简单地从object类继承。
有了Person类的定义,就可以创建出具体的xiaoming、xiaohong等实例。创建实例使用 类名+(),类似函数调用的形式创建:
xiaoming = Person()
xiaohong = Person()
注:python 2 创建类与python 3 不同
py 2.2 后继承 object 的目的是使这个类成为 new style class,没有继承 object 的为传统 classic class,
在py 2.7.11进行了测试
>>> class A(object):
... pass
...
>>> print(type(A))
<type 'type'>
>>> class B():
... pass
...
>>> print(type(B))
<type 'classobj'>
# 可见2个type是不同的
>>> print dir(A)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> print dir(B)
['__doc__', '__module__']
# 属性也是不一样的
而py 3.5.2:
class A(object):
pass
print(type(A))
print(dir(A))
class B():
pass
print(type(B))
print(dir(B))
<class 'type'>
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
<class 'type'>
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
说明 py 3.5 object 已经作为默认基类被继承了(跟 java 一样). 字段 : 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同 。 普通字段属于 对象 , 静态字段属于 类 . class Province:
# 静态字段
country = '中国'
def __init__(self, name):
# 普通字段
self.name = name
# 直接访问普通字段
obj = Province('河北省')
print(obj.name)
# 直接访问静态字段
print(Province.country)
静态字段在内存中只保存一份 , 普通字段在每个对象中都要保存一份
方法 : 方法包括:普通方法、静态方法和类方法,三种方法在 内存中都归属于类 ,区别在于调用方式不同。 普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
静态方法:由类调用;无默认参数; #!/usr/bin/env python
# Version = 3.5.2
# __auth__ = '无名小妖'
class Foo:
def __init__(self, name):
self.name = name
def ord_func(self):
""" 定义普通方法,至少有一个self参数 """
print('普通方法')
@classmethod
def class_func(cls):
""" 定义类方法,至少有一个cls参数 """
print('类方法')
@staticmethod
def static_func():
""" 定义静态方法 ,无默认参数"""
print('静态方法')
# 调用普通方法
f = Foo('那么')
f.ord_func()
# 调用类方法
Foo.class_func()
# 调用静态方法
Foo.static_func()
尽量不要用对象执行静态方法和类方法。
属性: Python中的属性其实是 普通方法 的变种。
class Foo:def func(self):
pass
# 定义属性
@property
def prop(self):
print('xxx')
# ############### 调用 ###############
foo_obj = Foo()
foo_obj.func()
foo_obj.prop #调用属性
由属性的定义和调用要注意一下几点:
定义时,在普通方法的基础上添加 @property 装饰器; 定义时,属性 仅有一个 self参数调用时,无需 括号
方法:foo_obj.func()
属性:foo_obj.prop
注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象 。
属性的定义有两种方式: 装饰器 即:在方法上应用装饰器 静态字段 即:在类中定义值为property对象的静态字段 装饰器方式: 在类的普通方法上应用@property装饰器#!/usr/bin/env python
# Version = 3.5.2
# __auth__ = '无名小妖'
class Pager():
def __init__(self,all_count):
self.all_count = all_count
@property
def all_pager(self):
a1,a2 = divmod(self.all_count,10)
if a2 == 0:
x = a1
else:
x = a1 + 1
return x
@all_pager.setter
def all_pager(self,value):
self.all_count = value * 10
@all_pager.deleter
def all_pager(self):
print('deleter') p = Pager(101) print(p.all_pager) # 自动执行 @property 修饰的 all_pager方法,并获取方法的返回值
p.all_pager = 123 # 自动执行 @all_pager.setter 修饰的 all_pager方法,并将 123 赋值给方法的参数
del p.all_pager # 自动执行 @all_pager.deleter 修饰的 price 方法 11
123
deleter 继承: 即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是 模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。 实例化: 创建一个类的实例,类的具体对象。 方法: 类中定义的函数。 对象: 通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。