面向对象编程是一种程序设计思想,把对象作为程序的基本单元,一个对象里面包含了数据以及操作数据的方法,称为类的属性和方法。

基础-定义、实例化、实例属性

用class来定义对象,类名首字母大写,如果这个类没有父类,则参数使用object类(object可以省略不写);如果这个类有父类,参数就是父类的名称。可以用一个特殊的方法__init()__方法来对类的属性进行定义。第一个参数固定是self,但是在创建实例的时候self是不需要传入的,self表示实例本身。类中还可以定义方法。第一个参数也是self,后面的参数和普通函数一样。要调用一个方法,只需要在实例变量上直接调用,除了self不用传递,其他参数正常传入。通过实例.方法的方式进行调用。

class Person(object):

    def __init__(self, name, age):
self.name = name
self.age = age def print_age(self):
print('%s: %s' % (self.name, self.age))
>>>tt = Person('taoting',23)
>>>tt.print_age()
tt:23

在类定义中我们可以随时为类增加方法,而外部的代码不需要做改变。因此,面向对象的编程时非常方便进行扩展的。

方法中带外部参数的类示例:

注意区别:name和age参数是类固有的属性,在定义实例时就需要传入,而city是实例的方法的参数,只有调用类的方法时才传入

class Person(object):

    def __init__(self, name, age):
self.name = name
self.age = age def print_age(self, city):
print('name: %s age: %s city: %s' % (self.name, self.age, city)) tt = Person('taoting',23)
tt.print_age('shanghai')
#结果:name: taoting age: 23 city: shanghai

类属性

类属性是直接在class中定义的属性,归类所有,类的所有属性都能访问。

class Person:
count = 0
def __init__(self, name, age):
self.name = name
self.age = age
Person.count = Person.count + 1 tt = Person('taoting', 23)
print(tt.count)#1 

访问权限

在实例中传入的参数是可以通过实例名.参数名进行修改的。有时我们想让内部的一些属性不被外部访问,就可以在属性名称前加上两个下划线__,将属性编程一个私有变量,外部无法访问。

class Person(object):

    def __init__(self, name, age):
self.__name = name
self.__age = age tt = Person('taoting',23)
tt.__name
#报错:AttributeError: 'Person' object has no attribute '__name'

那么要想在外部代码中访问内部的name和age变量怎么办呢?

答案:在类中增加方法,在方法中返回变量值。这样就确保了外部不能随便修改变量值,但还能访问到。

class Person(object):

    def __init__(self, name, age):
self.__name = name
self.__age = age def get_name(self):
return self.__name def get_age(self):
return self.__age tt = Person('taoting',23)
print(tt.get_name())
#结果:taoting

进一步地,还是有办法能够修改变量值:通过在类中定义方法将要修改的值传入并赋值给__开头的变量:

class Person(object):

    def __init__(self, name, age):
self.__name = name
self.__age = age def set_name(self, name):
self.__name = name
return self.__name def set_age(self, age):
self.__age = age
return self.__age tt = Person('taoting',23) print(tt.set_name('tt'))
#结果:tt
print(tt.set_name(18))
#结果:18

通过先设置不能外部修改,再定义供外部程序修改的方法的方式,能够在方法中对参数做检测、处理、等等。

@property (静态属性) 还可以将一个方法变成一个属性,在调用的时候像调用一个属性一样,不需要加括号。相当于将一个方法进行了封装,调用者不会发现背后的逻辑。静态属性可以访问类属性和实例属性。我们可以在方法里面对属性进行判断,也可以将属性设置成可读可写和只可读:

#width、height和area方法通过@property变成了类的属性。
#width、height可以读和写,而area只读
class Area(object):
@property
def width(self):
return self._width
@width.setter
def width(self,value):
self._width = value
@property
def height(self):
return self._height
@height.setter
def height(self,value):
self._height = value
@property
def area(self):
return self._width * self._height a = Area()
a.width = 10
a.height = 8
print(a.area)#
a.area = 100#AttributeError: can't set attribute #在可写的属性里面我们可以对传入的值进行检查
class Area(object):
@property
def width(self):
return self._width
@width.setter
def width(self,value):
if value < 0:
raise ValueError('width must be greater than 0!')
self._width = value
@property
def height(self):
return self._height
@height.setter
def height(self,value):
self._height = value
@property
def area(self):
return self._width * self._height a = Area()
a.width = -5#ValueError: width must be greater than 0!

对于实例化的对象,我们可以定义类的没有定义的属性,比如上例中,我们可以定义:a.length = 6。只对本实例化对象有效。

那么,在类中我们可以指定实例化对象中能够定义的属性,用__slots__实现:

class Area(object):
__slots__ = ('name','color')
@property
def width(self):
return self._width
@width.setter
def width(self,value):
if value < 0:
raise ValueError('width must be greater than 0!')
self._width = value
@property
def height(self):
return self._height
@height.setter
def height(self,value):
self._height = value
@property
def area(self):
return self._width * self._height a = Area()
a.name = 'a'
a.length = 6#AttributeError: 'Area' object has no attribute 'length'

当为实例新建一个属性时就会报错。a.length就是调用了setattr方法,也就是a.__dict__['length'] = 6。而定义了__slots__之后,实例就没有__dict__方法了,因此会报错。那么意味着__slots__指定了实例的所有属性。

这种方式的好处在于能够节省内存,当我们创建成千上万个实例时,如果不用__slots__,那么python会为每个实例创建一个属性字典,这样非常占用内存空间。当我们定义__slots__后,__slots__就会为实例使用一种更加紧凑的内部表示。实例通过一个很小的固定大小的数组来创建,而不是为每个实例定义一个属性字典。

@classmethod(类方法)可以定义只跟类相关的操作,定义不用实例化即可调用的函数。cls表示跟类绑定,是固定的参数。类方法可以访问类的数据属性和函数属性,但是不能访问实例的数据属性和函数属性。

class Person:
tag = 2
def __init__(self, name, age):
self.name = name
self.age = age #将方法属性化,只跟类有关,不用实例化,cls就是类本身
@classmethod
def attr(cls):
print(cls.tag) Person.attr()#这样调用就可以做一些只跟类有关的操作

@staticmethod(静态方法),类的工具包,跟类没关系,也跟实例没关系。只是名义上属于类管理,但是不能访问类属性和实例属性。

class Person:
def __init__(self, name, age):
self.name = name
self.age = age
@staticmethod
def run(a,b):
print('%s and %s are runing...' % (a,b)) Person.run('tt','rr')#类可以直接调用
p1 = Person('tt',18)#实例也可以调用
p1.run('tt','rr')

继承

类的继承类似于动物-->猫的关系,猫是属于动物的,猫具有动物的特征。

在类的继承里,子类继承父类的属性和方法。父类又称为基类、超类

class Person(object):

    def __init__(self, name, age):
self.name = name
self.age = age def run(self):
print('Person is runing...')
print('name: %s age: %s' % (self.name, self.age)) def attr(self):
print('This is a super method!') class Male(Person): def run(self):
print('Male is runing...')
print('name: %s age: %s' % (self.name, self.age)) tt = Person('taoting', 23)
tt.run()
#结果:
#Person is runing...
#name: taoting age: 23
ZL = Male('zhaoliang', 26)
ZL.run()
#结果:
#Male is runing...
#name: zhaoliang age: 26 ZL.attr()
#结果:This is a super method!

从以上代码我们可以看到:

1.子类可以直接继承父类的属性和方法

2.当父类和子类中有相同的方法时,子类调用方法时优先在子类中搜索,所以上面子类调用run方法时,是调用的子类里面的run方法,而不是父类里面的

实例对象之间的交互

在面向对象的编程中,就是大量的实例对象之间的交互。

我们创建两个类Alien和Automan,再分别实例出两个角色:alien1和automan1,来模拟两者之间的交互。

class Alien:
def __init__(self, name, life_value = 500):
self.name = name
self.life_value = life_value def attack(self, enemy):
enemy.life_value -= 50 class Automan:
def __init__(self, name, life_value = 1000):
self.name = name
self.life_value = life_value def attack(self, enemy):
enemy.life_value -= 10 alien1 = Alien('怪兽')
automan = Automan('迪迦')
print(alien1.life_value)#
print(automan.life_value)#
automan.attack(alien1)
print(alien1.life_value)#
print(automan.life_value)#

类的组合

在一个类中我们可以实例化另外一个类,作为这个类的属性,这叫类的组合:

class F1:
def f1(self):
print('F1.f1') class F2:
def __init__(self):
self.ff2 = F1()
def f1(self):
print('F2.f1') c1 = F2()
c1.ff2.f1()#F1.f1

Python——面向对象编程的更多相关文章

  1. python 面向对象编程学习

    1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...

  2. python 面向对象编程(一)

    一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class c ...

  3. Python面向对象编程指南

    Python面向对象编程指南(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1SbD4gum4yGcUruH9icTPCQ 提取码:fzk5 复制这段内容后打开百度网 ...

  4. python面向对象编程进阶

    python面向对象编程进阶 一.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 ...

  5. Python面向对象编程(下)

    本文主要通过几个实例介绍Python面向对象编程中的封装.继承.多态三大特性. 封装性 我们还是继续来看下上文中的例子,使用Student类创建一个对象,并修改对象的属性.代码如下: #-*- cod ...

  6. Python 面向对象编程——访问限制

    <无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...

  7. Python 面向对象编程 继承 和多态

    Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...

  8. Python 面向对象编程基础

    Python 面向对象编程基础 虽然Pthon是解释性语言,但是Pthon可以进行面向对象开发,小到 脚本程序,大到3D游戏,Python都可以做到. 一类: 语法: class 类名: 类属性,方法 ...

  9. python面向对象编程学习

    python面向对象编程 基本概念理解 面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作 ...

  10. Python面向对象编程——继承与派生

    Python面向对象编程--继承与派生 一.初始继承 1.什么是继承 继承指的是类与类之间的关系,是一种什么"是"什么的关系,继承的功能之一就是用来解决代码重用问题. 继承是一种创 ...

随机推荐

  1. 基于drone构建CI-CD系统

    kubernetes集群三步安装 CI 概述 用一个可描述的配置定义整个工作流 程序员是很懒的动物,所以想各种办法解决重复劳动的问题,如果你的工作流中还在重复一些事,那么可能就得想想如何优化了 持续集 ...

  2. div span img对齐,垂直居中对齐问题

    我想你们在前端开发中或多或少都遇到过这种问题,文字和图片不能平齐,很是头疼. HTML代码: <div class="">小太阳<span>小太阳</ ...

  3. codeforces 347A - Difference Row

    给你一个序列,让你求(x1 - x2) + (x2 - x3) + ... + (xn - 1 - xn).值最大的一个序列,我们化简一下公式就会发现(x1 - x2) + (x2 - x3) + . ...

  4. 使用eclipse编写和运行java程序(基础)

    1.首先java程序的运行你需要下载和安装JDK,这是java运行的必备环境. 2.在桌面上找到eclipes,双击打开. 3.在eclipes启动的过程中,会弹出一个窗口,让你填写java工作区的保 ...

  5. Git 学习笔记之(一) 使用 git gui 从github上下载代码

    背景: 目前一些开源代码均在 GitHub上管理的,包括自己写的代码也可以放在上面进行管理.但问题是,当你换一台电脑,想要将你自己放在 GitHub 上的代码工程下载下来的时候,会遇到各种问题,目前可 ...

  6. c#小灶——使用visual studio编写第一个程序

    虽然,写程序有文本编辑器和编译器就已经足够,但是,我们为了增加工作效率还是要使用IDE. 我们接下来所有的教程都将会在visual studio中实现,visual studio简称vs,是微软开发的 ...

  7. Oracle SQL常用内置系统函数总结

    Oracle数据库  内置系统函数主要分为以下类别:数学函数.字符串函数.日期函数.转换函数.聚合函数.分析聚合函数 一.数学函数 ------------返回数字       abs(n):返回数字 ...

  8. word 文档导出 (freemaker+jacob)--java开发

    工作中终于遇到了 需要导出word文旦的需求了.由于以前没有操作过,所以就先百度下了,基本上是:博客园,简书,CDSN,这几大机构的相关帖子比较多,然后花了2周时间 才初步弄懂.  学习顺序: 第一阶 ...

  9. Jenkins 持续集成持续发布使用搭建基础

    一.环境搭建基础 1.持续集成.持续交付.持续部署概念 ①.集成: 是指软件多人研发的部分软件代码整合交付,以便尽早发现个人开发部分的问题:持续集成:强调开发人员提交了新代码之后,立刻进行构建(单元) ...

  10. 字符串(String、StringBuffer、StringBuilder)进阶分析

    转载自https://segmentfault.com/a/1190000002683782 我们先要记住三者的特征: String 字符串常量 StringBuffer 字符串变量(线程安全) St ...