Python面向对象编程和模块
在面向对象编程中,你编写表示现实世界中的事物和情景的类,并基于这些类来创建对象。
编写类时,你定义一大类对象都有的通用行为。基于类创建对象时,每个对象都自动具备这种通用行为,然后根据需要赋予每个对象独特的个性。
根据类来创建对象被称为实例化,这让你能够使用类的实例。你可以在实例中存储一些信息或者定义一些操作。
你还可以编写一些类来扩展既有类的功能,让相似的类能够高效地共享代码。
1. 面向对象编程
1.1 创建和使用类
class Car():
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def get_descriptive_name(self):
long_name = str(self.year) + ' ' + self.make + ' ' + self.model
return long_name.title()
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
# 2016 Audi A4
在Python中,类的首字母大写。类中的函数称为方法。
__init__()
方法是一个特殊的方法,每当创建实例的时候,Python都会自动运行它。
这个方法中的形参self
必不可少,还必须位于其他形参的前面。每个与类相关联的方法调用都自动传递实参self
,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
1.2 访问限制
# test.py
class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def print_score(self):
print('%s: %s' % (self.__name, self.__score))
>>> from test import Student
>>> student = Student('Bart Simpson', 59)
>>> student.__name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__name'
上面通过实例访问变量__name
时报错了。实际上,以两个下划线开头的__name
为私有变量。
不能访问变量__name
是因为Python解释器对外把__name
改成了_Student__name
。
>>> from test import Student
>>> student = Student('Bart Simpson', 59)
>>> student._Student__name
'Bart Simpson'
1.3 继承与多态
子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。
1.3.1 继承
class Car():
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def get_descriptive_name(self):
long_name = str(self.year) + ' ' + self.make + ' ' + self.model
return long_name.title()
class ElectriCar(Car): # 定义子类时,必须在括号内指定父类的名称。
def __init__(self, make, model, year):
super().__init__(make, model, year) # 调用父类的__init__()方法,从而继承父类的所有属性
my_tesla = ElectriCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
# 2016 Tesla Model S
class ElectriCar(Car):
def __init__(self, make, model, year):
super().__init__(make, model, year)
self.battery_size = 70 # 子类的属性
def describe_battery(self): # 子类的方法
print("This car has a " + str(self.battery_size) + "-kWh battery.")
my_tesla = ElectriCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()
# 2016 Tesla Model S
# This car has a 70-kWh battery.
1.3.1 多态
# 重写父类的方法(多态)
class Parent:
def myMethod(self):
print ('调用父类方法')
class Child(Parent):
def myMethod(self):
print ('调用子类方法')
c = Child()
c.myMethod() # 调用子类方法
super(Child,c).myMethod() # 调用父类方法
1.3.3 将实例用作属性
class ElectriCar(Car):
def __init__(self, make, model, year):
super().__init__(make, model, year)
self.battery = Battery() # 将实例用作属性
class Battery():
def __init__(self, battery_size=70):
self.battery_size = battery_size
def describe_battery(self):
print("This car has a " + str(self.battery_size) + "-kWh battery.")
my_tesla = ElectriCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
# 2016 Tesla Model S
# This car has a 70-kWh battery.
1.3.4 多重继承
class people:
name = ''
age = 0
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))
class student(people):
grade = ''
def __init__(self,n,a,w,g):
people.__init__(self,n,a,w)
self.grade = g
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
class speaker():
topic = ''
name = ''
def __init__(self,n,t):
self.name = n
self.topic = t
def speak(self):
print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))
class sample(speaker,student):
a =''
def __init__(self,n,a,w,g,t):
student.__init__(self,n,a,w,g)
speaker.__init__(self,n,t)
>>> from test import people, student, speaker, sample
>>> test = sample("Tim",25,80,4,"Python")
>>> test.speak() # 调用的是speaker的speak()方法
我叫 Tim,我是一个演说家,我演讲的主题是 Python
class sample(student,speaker): # 调换了一下括号内父类的顺序
a =''
def __init__(self,n,a,w,g,t):
student.__init__(self,n,a,w,g)
speaker.__init__(self,n,t)
>>> from test import people, student, speaker, sample
>>> test = sample("Tim",25,80,4,"Python")
>>> test.speak()
Tim 说: 我 25 岁了,我在读 4 年级
1.4 实例属性和类属性
由于Python是动态语言,根据类创建的实例可以任意绑定属性。
class Student(object):
def __init__(self, name):
self.name = name # 给实例绑定属性
s = Student('Bob')
s.score = 90 # 给实例绑定属性
class Student(object):
name = 'Student' # 类属性
实例属性属于各个实例所有,互不干扰。
类属性属于类所有,所有实例共享一个属性。
相同名称的实例属性将屏蔽掉类属性,不要对实例属性和类属性使用相同的名字。
2. 模块
在Python中,模块就是一个后缀名为.py的文件。
使用模块还可以避免函数名和变量名冲突。但是,名字不要与内置函数名冲突。
为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包。
请注意,每一个包目录下面都会有一个__init__.py
的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py
可以是空文件,也可以有Python代码,因为__init__.py
本身就是一个模块,而它的模块名就是包目录名。
自己创建模块时要注意命名,不能和Python自带的模块名称冲突。
2.1 作用域
类似__xxx__
这样的变量是特殊变量,可以被直接引用。
# hello.py
······
if __name__ == '__main__': # __name__为特殊变量
test()
当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__
置为__main__
,因此这里将执行if
语句块里面的代码。而如果我们在其他地方导入hello模块时,将不执行if
语句块里面的代码。
类似_xxx
和__xxx
这样的函数或变量就是非公开的(private),不应该被直接引用。
Python并没有一种方法可以完全限制访问private函数或变量,但是private函数或变量不应该被直接引用。
2.2 导入类
导入单个类
from car import Car # from 模块名 import 类
my_new_car = Car('audi', 'model s', 2016)
导入多个类
from car import Car, ElectricCar
导入整个模块
import car # import 模块名
my_beetle = car.Car('volkswagen', 'beetle', 2016)
导入模块中的所有类
from car import * # 不推荐
参考资料:
- Python3 教程 | 菜鸟教程
- Python教程 - 廖雪峰的官方网站
- 《Python编程从入门到实践》——【美】Eric Matthes 著
Python面向对象编程和模块的更多相关文章
- python 面向对象编程学习
1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...
- Python面向对象编程指南
Python面向对象编程指南(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1SbD4gum4yGcUruH9icTPCQ 提取码:fzk5 复制这段内容后打开百度网 ...
- python面向对象编程进阶
python面向对象编程进阶 一.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 1 ...
- 图解python | 面向对象编程
作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/56 本文地址:http://www.showmeai.tech/article-det ...
- python 面向对象编程(一)
一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class c ...
- Python面向对象编程(下)
本文主要通过几个实例介绍Python面向对象编程中的封装.继承.多态三大特性. 封装性 我们还是继续来看下上文中的例子,使用Student类创建一个对象,并修改对象的属性.代码如下: #-*- cod ...
- Python 面向对象编程——访问限制
<无访问限制的对象> 在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑.但是,从前面Student类的定义来看(见:Py ...
- Python 面向对象编程 继承 和多态
Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...
- Python 面向对象编程基础
Python 面向对象编程基础 虽然Pthon是解释性语言,但是Pthon可以进行面向对象开发,小到 脚本程序,大到3D游戏,Python都可以做到. 一类: 语法: class 类名: 类属性,方法 ...
随机推荐
- 【亲测有效】运行docker ps 出现Got permission denied问题的解决方案
问题描述 今天在运行 docker ps 命令的时候出现如下问题: Got permission denied while trying to connect to the Docker daemon ...
- Ionic 2 中生命周期的命名改变及说明
原文发表于我的技术博客 本文简要整理了在 Ionic 2 的版本中生命周期命名的改变,以及各个事件的解释. 原文发表于我的技术博客 在之前的课程中讲解了 Ionic 生命周期的命名以及使用,不过在 I ...
- CrackMe-005全破详解(图文+源码)--上篇
逆向破解 | 逆向 | 逆向分析 | CrackMe | Crack | CrackMe5 | CrackMe05 前言 CrackMe005,都说比较变态,很多人给放过去了,但是我还是决定上了它,既 ...
- Linux下防御DDOS攻击的操作梳理
DDOS的全称是Distributed Denial of Service,即"分布式拒绝服务攻击",是指击者利用大量“肉鸡”对攻击目标发动大量的正常或非正常请求.耗尽目标主机资源 ...
- 《Linux内核设计与实现》第四章学习笔记
<Linux内核设计与实现>第四章学习笔记 ——进程调度 姓名:王玮怡 学号:20135116 一.多任务 1.多任务操作系统的含义 多任务操作系统就是能同时并发地交 ...
- linux第二次读书笔记
<Linux内核设计与实现>读书笔记 第五章 系统调用 第五章系统调用 系统调用是用户进程与内核进行交互的接口.为了保护系统稳定可靠,避免应用程序恣意忘形. 5.1与内核通信 系统调用 ...
- 01springboot快速入门
SpringBoot快速入门 springboot的宗旨是习惯大于配置,所以spring里面大量使用了默认的配置来简化spring的配置.spring Boot的主要优点: 为所有Spring开发者更 ...
- shell脚本--cut命令与awk简单使用
cut:对内容进行列切割 -d 后面的是分割符,表示用什么符号来分割符来分割列,分隔符使用引号括起来: -f后面跟着要选择的字段列,从1开始,表示第一列,如果要多列,可以用逗号分隔 : -c参数后面跟 ...
- Fixed the bug:while running alert/confirm in javascript the chrome freezes
显示高级设置... 系统 -> 使用硬件加速模式(如果可用) 操作系统如果不支持硬件加速,却启动此项,就悲催了.小伙伴们可别瞎点了,太吃亏. 现象alert/confirm一执行,chrome ...
- 如何使用git在github上开发的时候和别人在别人仓库上进行协作编程,最后再统一提交
因为总是忘记,所以记录一下. 这里首先需要添加你需要操作对象的仓库到你的远程仓库并给个名字,才能进行操作.这里我用我同事的邮箱做比喻.(如果对方为私有仓库,你必须要有同样的权限) 使用命令 git r ...