python如何对一个属性或方法进行封装_日知录(五):python面对对象编程

OOP

理解OOP的想法

终于到这个part了,如何面对对象编程呢?

来一个高大上的定义:面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

之前学的是C语言,是一种面向过程的程序设计思想。

1.在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念。

2.类(Class)和实例(Instance)的概念

Class是一种抽象概念,比如我们定义的Class——Student,是指学生这个概念,而实例(Instance)则是一个个具体的Student,比如,Bart Simpson和Lisa Simpson是两个具体的Student。

3.面向对象的设计思想是抽象出Class,根据Class创建Instance。

4.我大白话讲讲:简单点理解,动物分类:界门纲目科属种,比如狼这一实例属于犬科,犬科的基本特点,在_init_内定义(数据封装)。狼在继承犬科(继承)这一基本特点后,还有一些自己的特点,或者可以重新定义一些基本特点(多态性)。同时,犬科与猫科之间,必定是由一些特点是根本性的,不能改变的。(即 该类的私有属性)

接下来看看我们对象的特性

特点一:数据封装

# -*- coding: UTF-8 -*-

#创建一个新的抽象类:用class语句,Student为类的名称

class Student(object):

#__init__()是一种特殊的方法,被称为类的构造函数或初始化方法

def __init__(self,name,score):

self.name=name

self.score=score

#slef代表类的实例,self在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。

def print_score(self):

print('%s:%s' % (self.name,self.score))

#创建类的实例对象bart,并通过__init__方法接收参数

bart = Student('Bart Simpson', 5)

#访问对象的属性.print_score()

bart.print_score()

该例中定义了print_score()方法,即在Student类的内部定义访问数据的函数print_score(),这样,就把“数据”给封装起来了。这些封装数据的函数是和Student类本身是关联起来的,我们称之为类的方法。

定义方法时进行数据封装

1.定义一些特殊方法

一般是系统定义名字,类似__init()__之类的

__foo __(): 定义的是特殊方法,一般是系统定义名字 ,类似 __ init __() 之类的。

_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *

2.定义类的私有属性

__private_attrs: 两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs

3.定义类的方法

def 关键字:在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数

4.定义类的私有方法

__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用 self.__private_methods

试图从外部访问私有变量时的报错

# -*- coding: UTF-8 -*-

class JustCounter:

__secretCount = 0 # 私有变量

publicCount = 0 # 公开变量

def count(self):

self.__secretCount += 1

self.publicCount += 1

print(self.__secretCount)

counter = JustCounter()

counter.count()

counter.count()

print(counter.publicCount)

print(counter.__secretCount )

# 报错,实例不能访问私有变量

AttributeError: 'JustCounter' object has no attribute '__secretCount'

Python不允许实例化的类访问私有数据,但你可以使用 object._className__attrName( 对象名._类名__私有属性名 )访问属性

# -*- coding: UTF-8 -*-

class Runoob:

__site = "www.runoob.com"

runoob = Runoob()

print (runoob._Runoob__site)

结果

www.runoob.com

特点二:继承

当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)

1.继承1个类

class 派生类名(基类名)

···

2.继承多个类

class A: # 定义类 A

.....

class B: # 定义类 B

.....

class C(A, B): # 继承类 A 和 B

.....

3.方法重写

如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法

class Animal(object):

def run(self):

print('Animal is running...')

class Dog(Animal):

def run(self):

print('Dog is running...')

def eat(self):

print('Eating meat...')

class Cat(Animal):

def run(self):

print('Cat is running...')

dog = Dog()

dog.run()

cat = Cat()

cat.run()

运行结果

Dog is running...

Cat is running...

当子类和父类都存在相同的run()方法时,调用时子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()。这样,我们就获得了继承的另一个好处:多态

特点三:多态性

多态的好处就是,当我们需要传入Dog、Cat、Tortoise……时,我们只需要接收Animal类型就可以了,因为Dog、Cat、Tortoise……都是Animal类型,然后,按照Animal类型进行操作即可,牵一发而动全身的感觉,就是从父类更改就可以。由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态。

获取对象信息

在引用对象时,了解对象的类型和方法

1. type()

b_0_202007121705005620.jpg

2. isinstance()

要判断class的类型,可以使用isinstance()函数

3. dir()

要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list。

配合getattr()、setattr()以及hasattr(),我们可以直接操作一个对象的状态

b_0_202007121705018602.jpg

b_0_202007121705011771.jpg

b_0_202007121705035853.jpg

类属性与实例属性

给实例绑定属性的方法是通过实例变量,或者通过self变量

class Student(object):

def __init__(self, name):

self.name = name

s = Student('Bob')

s.score = 90

以下摘自廖雪峰老师的教程实例。

当我们定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到。来测试一下:

>>>class Student(object):

name = 'Student'

>>>s = Student() # 创建实例s

>>>rint(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性

Student

>>>print(Student.name) # 打印类的name属性

Student

>>>s.name = 'Michael' # 给实例绑定name属性

>>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性

Michael

>>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问

Student

>>> del s.name # 如果删除实例的name属性

>>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了

Student

在编写程序的时候,不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。

本文地址:https://blog.csdn.net/weixin_43883903/article/details/107175514

希望与广大网友互动??

点此进行留言吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值