Python面向对象 | 初识
一、面向对象编程
类 : 具有相同属性和技能的一类事物
对象: 就是对一个类的具体的描述
实例化:类——>对象的过程
使用面向对象的好处:
- 使得代码之间的角色关系更加明确
- 增强了代码的可扩展性
- 规范了对象的属性和技能
结构上, 面向对象可以分为两部分:属性和方法
属性又叫静态属性、静态字段、静态变量
方法又叫动态属性、函数
class A:
name = 'hello' #静态属性、静态字段、静态变量
def fun(self): #动态属性、方法、函数
pass
新建一个类,类名的首字母最好是大写的,规范一点,否则Pycharm有波浪号
1. 类属性
类的属性有两种方式查看
dir(类名):查出的是一个名字列表
类名.__dict__:查出的是一个字典,key为属性名,value为属性值
class Person:
静态变量 = 123
print(Person.__dict__) #内置的双下划线方法
执行输出:
{'__doc__': None, '静态变量': 123, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__dict__': <attribute '__dict__' of 'Person' objects>}
从结果中,可以找到 '静态变量': 123
特殊的类属性
类名.__name__ # 类的名字(字符串) 类名.__doc__ # 类的文档字符串 类名.__base__ # 类的第一个父类(在讲继承时会讲) 类名.__bases__ # 类所有父类构成的元组(在讲继承时会讲) 类名.__dict__ # 类的字典属性 类名.__module__ # 类定义所在的模块 类名.__class__ # 实例对应的类(仅新式类中)
2. 引用静态变量
类名.__dict__['静态变量名'] 可以查看,但是不能删改 类名.静态变量名 直接就可以访问,可以删改 del 类名.静态变量名 删除一个静态变量
3. 引用动态变量
类名.方法名 查看这个方法的内存地址 类名.方法名(实参) 调用了这个方法,必须传一个实参,这个实参传给了self
class Person:
静态变量 = 123 #静态属性,静态变量
role = 'person'
def f1(self): #默认带一个参数self,方法,动态属性
print(1234567)
#引用动态变量
Person.f1() # 执行报错:TypeError: f1() missing 1 required positional argument: 'self' # 提示缺少一个参数self
随便传一个参数,再次执行
Person.f1(1)
只要是类的方法,必须要传self。self的名字,是约定俗成
二、面象对象 VS 函数(方法)
产生一个实例(对象)的过程:对象 = 类名()

实例化对象的过程有几步:
- 实例化对象在内存中产生一个对象空间(内存地址)。
- 自动执行 __init__方法,将对象空间传给了self参数。
- 在 __init__方法中,给对象空间封装一些静态属性。
1. __init__方法
初始化方法,功能就是给对象self封装属性
class Person:
role = 'person' #静态属性
def __init__(self,name,sex,hp,ad):
self.name = name
self.sex = sex
self.hp = hp
self.ad = ad
summer = Person('summer','M',1,5)
print(summer.__dict__)
广义上的属性,是指对象的属性
2. 类里面的方法
在类里面的def 一般叫方法。没有顺序之分,一般把init放到第一个.
class Person:
role = 'person' #静态属性
def __init__(self,name,sex,hp,ad):
self.name = name
self.sex = sex
self.hp = hp
self.ad = ad
def attack(self):
print('{}发起了一次攻击'.format(self.name))
summer = Person('ss','M',1,5)
# 执行类方法,下面2种方法效果等同
Person.attack(summer) # attack是和Person关联起来的,所以外部可以直接调用attack方法
summer.attack()
'''
执行输出:
ss发起了一次攻击
ss发起了一次攻击
'''
方法的调用 :
1.类名.方法名(对象名) 方法中的self参数就指向这个对象
2.对象名.方法名() 这样写相当于方法中的self参数直接指向这个对象,推荐使用
三、类名、对象的使用
1. 从类名的角度研究类
① 查看类中所有的属性和方法:__dict__。虽然__dict__也能查看类中某一个属性,但是通常用来查看类中的所有属性和方法,不做其他用途
② 增删改查类中的属性:用万能的点(类中没有该属性就增,有该属性就改)
③ 操作类中的方法:一般不通过类名(一般通过对象名)
类名操作静态属性
(1)查看类中的所有内容:类名.__dict__方式
class Human:
mind = '有思想' # 第一部分:静态属性 属性 静态变量 静态字段
dic = {}
l1 = []
def work(self): # 第二部分:方法 函数 动态属性
print('人类会工作')
print(Human.__dict__)
print(Human.__dict__['mind'])
Human.__dict__['mind'] = '无脑' # 报错
通过.__dict__这种方式只能查询,不能增删改.。第一种方式只用户查询全部内容(一般不用单独属性查询).
(2)通过万能的点 可以增删改查类中的单个属性
class Human:
mind = '有思想'
def work(self): # 第二部分:方法 函数 动态属性
print('人类会工作')
Human.walk = '直立行走' # 增
del Human.mind # 删
Human.mind = '无脑' # 改
print(Human.mind) # 查
对以上两种做一个总结:
- 如果想查询类中的所有内容,通过__dict__方法;
- 如果只是操作单个属性则用万能的点的方式。
类名操作动态方法
除了两个特殊方法:静态方法,类方法之外,一般不会通过类名操作一个类中的方法。
class Human:
mind = '有思想' # 第一部分:静态属性 属性 静态变量 静态字段
def work(self): # 第二部分:方法 函数 动态属性
print('人类会工作')
def tools(self):
print('人类会使用工具')
Human.work(111)
Human.tools(111)
# 下面可以做,但不用。
Human.__dict__['work'](111)
2. 从对象的角度研究类
实例化一个对象总共发生了三件事:
- 在内存中开辟了一个对象空间。
- 自动执行类的__init__方法,并将这个对象空间(内存地址)传给__init__方法的第一个位置参数self。
- 在__init__ 方法中通过self给对象空间添加属性。
对象操作对象空间
- 对象查看对象空间的所有属性__dict__
- 对象操作对象的某个属性,增删改查,用万用的点(对象中没有该属性就增,有该属性就减)
- 对象操作类空间的属性,只能查
- 对象操作类空间的方法:万能的点
(1)对象查询对象中所有属性 对象.__dict__
class Human:
mind = '有思想'
language = '实用语言'
def __init__(self,name,sex,age,hobby):
# self 和 obj 指向的是同一个内存地址同一个空间,下面就是通过self给这个对象空间封装四个属性。
self.n = name
self.s = sex
self.a = age
self.h = hobby
obj = Human('barry','男',18,'运动')
print(obj.__dict__) # {'n': 'barry', 'h': '运动', 's': '男', 'a': 18}
(2)对象操作对象中的单个属性 万能的点 .
class Human:
mind = '有思想'
language = '实用语言'
def __init__(self,name,sex,age,hobby):
# self 和 obj 指向的是同一个内存地址同一个空间,下面就是通过self给这个对象空间封装四个属性。
self.n = name
self.s = sex
self.a = age
self.h = hobby
obj = Human('barry','男',18,'运动')
obj.job = 'IT' # 增
del obj.n # 删
obj.s = '女' # 改
print(obj.s) # 查
(3)对象查看类中的属性
class Human:
mind = '有思想'
language = '实用语言'
def __init__(self,name,sex,age,hobby):
self.n = name
self.s = sex
self.a = age
self.h = hobby
obj = Human('barry','男',18,'运动')
print(obj.mind) # 有思想
print(obj.language) # 实用语言
(4)对象操作类中的方法
class Human:
mind = '有思想'
language = '实用语言'
def __init__(self,name,sex,age,hobby):
self.n = name
self.s = sex
self.a = age
self.h = hobby
def work(self):
print(self)
print('人类会工作')
def tools(self):
print('人类会使用工具')
obj = Human('barry','男',18,'运动')
obj.work()
obj.tools()
'''
执行输出:
<__main__.Human object at 0x000001576C1808C8>
人类会工作
人类会使用工具
'''
一个类可以实例化多个对象
class Human:
mind = '有思想'
language = '实用语言'
def __init__(self,name,sex,age,hobby):
self.n = name
self.s = sex
self.a = age
self.h = hobby
def work(self):
print(self)
print('人类会工作')
def tools(self):
print('人类会使用工具')
obj1= Human('李易峰','男',20,'拍戏')
obj2= Human('赵丽颖','女',18,'唱歌')
print(obj1,obj2)
print(obj1.__dict__)
print(obj2.__dict__)
'''
执行输出:
<__main__.Human object at 0x00000223534C0D88> <__main__.Human object at 0x00000223534C68C8>
{'n': '李易峰', 's': '男', 'a': 20, 'h': '拍戏'}
{'n': '赵丽颖', 's': '女', 'a': 18, 'h': '唱歌'}
'''
练习:在终端输出如下信息
小明,10岁,男,上山去砍柴
小明,10岁,男,开车去东北
小明,10岁,男,最爱大保健
老李,90岁,男,上山去砍柴
老李,90岁,男,开车去东北
老李,90岁,男,最爱大保健
老张…
class Person(object):
def __init__(self, name, age, sex='男', hobby=('上山去砍柴', '开车去东北', '最爱大保健')):
self.name = name
self.age = age
self.sex = sex
self.hobby = hobby
def info(self):
for i in self.hobby:
print('{},{}岁,{},{}'.format(self.name, self.age, self.sex, i))
ming = Person('小明', 10)
li = Person('老李', 90)
ming.info()
li.info()
扩展题:使用面向对象的方式编码三级菜单
将之前的代码复制粘贴过来,切割成面向对象方式
# -*- coding: utf-8 -*-
class AreaMenu(object):
def __init__(self):
self.zone = {
'山东': {
'青岛': ['四方', '黄岛', '崂山', '李沧', '城阳'],
'济南': ['历城', '槐荫', '高新', '长青', '章丘'],
'烟台': ['龙口', '莱山', '牟平', '蓬莱', '招远']
},
'江苏': {
'苏州': ['沧浪', '相城', '平江', '吴中', '昆山'],
'南京': ['白下', '秦淮', '浦口', '栖霞', '江宁'],
'无锡': ['崇安', '南长', '北塘', '锡山', '江阴']
},
'浙江': {
'杭州': ['西湖', '江干', '下城', '上城', '滨江'],
'宁波': ['海曙', '江东', '江北', '镇海', '余姚'],
'温州': ['鹿城', '龙湾', '乐清', '瑞安', '永嘉']
}
}
self.province = list(self.zone.keys())
self.run()
def run(self): # 省列表
while True:
print('省'.center(20, '*'))
for i in self.province: # 打印省列表
print('{}\t{}'.format(self.province.index(i) + 1, i))
province_input = input('请输入省编号,或输入q/Q退出:').strip()
if province_input.isdigit():
province_input = int(province_input)
if 0 < province_input <= len(self.province):
province_id = province_input - 1 # 省编号,由于显示加1,获取的时候,需要减1
city = list(self.zone[self.province[province_id]].keys()) # 城市列表
self.city(province_id, city) # 进入市区列表
else:
print("\033[41;1m省编号 {} 不存在!\033[0m".format(province_input))
elif province_input.upper() == 'Q':
break
else:
print("\033[41;1m输入省编号非法!\033[0m")
def city(self, province_id, city): # 市区列表
if province_id == '' or city == '':
return 'province_id 和 city 参数不能为空'
while True:
print('市'.center(20, '*'))
for j in city:
print('{}\t{}'.format(city.index(j) + 1, j))
city_input = input("请输入市编号,或输入b(back)返回上级菜单,或输入q(quit)退出:").strip()
if city_input.isdigit():
city_input = int(city_input)
if 0 < city_input <= len(city):
city_id = city_input - 1 # 市编号,由于显示加1,获取的时候,需要减1
county = self.zone[self.province[province_id]][city[city_id]] # 县列表
self.county(county) # 进入县列表
else:
print("\033[41;1m市编号 {} 不存在!\033[0m".format(city_input))
elif city_input.upper() == 'B':
break
elif city_input.upper() == 'Q':
exit() # 由于在多层while循环里面,直接exit退出即可
else:
print("\033[41;1m输入市编号非法!\033[0m")
def county(self, county): # 县列表
if county == '':
return 'county 参数不能为空'
while True:
print('县'.center(20, '*'))
for k in county:
print('{}\t{}'.format(county.index(k) + 1, k))
# 到县这一级,不能输入编号了,直接提示返回菜单或者退出
county_input = input("输入b(back)返回上级菜单,或输入q(quit)退出:").strip()
if county_input == 'b':
# 终止此层while循环,跳转到上一层While
break
elif county_input == 'q':
# 结束程序
exit()
else:
print("\033[41;1m已经到底线了,请返回或者退出!\033[0m")
if __name__ == '__main__':
AreaMenu()
执行输出:

Python面向对象 | 初识的更多相关文章
- python 面向对象-初识
一.分类 1.面向过程 2.面向函数 3.面向对象 二.类和对象 1.宏关 类是抽象的,对象是具体的 2.实例化 类->对象 3.类的作用 1)实例化成对象 实例化的过程,创建self对象,调用 ...
- 初识python面向对象
一.初识python面向对象: class Person: #使用class关键字定义一个类 age=0 #类变量(静态变量) def eat(self,food): #定义一个方法 self.age ...
- python递归 及 面向对象初识及编程思想
递归 及 面向对象初识及编程思想 一.递归 1.定义: 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. (1)递归就是在过程或函数里调用自身: (2)在使用递 ...
- python基础学习笔记——面向对象初识
面向对象初识 python中一切皆对象. 类有两种: 新式类:在py3中所有类都是新式类 经典类:在py2中只有类本身继承了object类才叫做新式类,默认是经典类 class Person: cou ...
- Python中面向对象初识到进阶
面向对象初识到进阶 # 面向对象结构: # class 类名: # def __init__(self,参数1,参数2): # self.对象的属性1 = 参数1 # self.对象的属性2 = 参数 ...
- Python面向对象01 /面向对象初识、面向对象结构、类、self、实例化对象
Python面向对象01 /面向对象初识.面向对象结构.类.self.实例化对象 目录 Python面向对象01 /面向对象初识.面向对象结构.类.self.实例化对象 1. 面向对象初识 2. 面向 ...
- python 面向对象专题(一):面向对象初识、面向对象结构、类、self、实例化对象
https://www.cnblogs.com/liubing8/p/11301344.html 目录 Python面向对象01 /面向对象初识.面向对象结构.类.self.实例化对象 1. 面向对象 ...
- python之面向对象初识
一.面向对象初识 1.结构上 面向对象分成两部分:属性.方法 class A: name = 'xiaoming' # 静态属性.静态变量.静态字段. def func1(self): # 函数.动态 ...
- python基础(17)继承类和面向对象初识
1.继承类 class Lm: money = 1000000 house = 5 def driver(self): print('会开车') class Mcb(Lm): def about_me ...
随机推荐
- PHP for的1个问题
PHP for的1个问题 <pre><?php for ($k = 13; $k > 0; $k--) { echo 'wef'; }?></pre>ps: ...
- thinkphp中怎么使用phpmailer发送邮件
phpmailer发送邮件是php开发者首选的一个邮件发送插件了,下面我来介绍怎么集成phpmailer到thinkphp框架了,有需要了解的朋友可参考. phpmailer发送邮件功能很强大,今天真 ...
- 明解C语言 入门篇 第十章答案
练习10-1 #include <stdio.h> void adjust_point(int*n) { ) *n = ; ) *n = 0; } int main() { int x; ...
- 固定定位导致$(window).scrollTop();获取滚动后到顶部距离总是为0
如下移动端索引列表页面(点击某元素后弹出的页面) 我想用 $(window).scrollTop(); 获取页面滚动后距离顶部的距离,但获取到的值总是0 期间查了很久,但都无疾而终,后来看到一篇 ...
- GET请求的请求参数最大长度
在HTTP规范RFC-2616中有这样一段描述: The HTTP protocol does not place any a priori limit on the length of a URI. ...
- 【03】Saltstack:远程执行
写在前面的话 远程执行可以说是我们使用 Saltstack 最为基础的目的.所以在这里专门作为单独的一篇来详细的聊聊. 远程执行命令 示例命令: salt '*' cmd.run 'w' 命令分析: ...
- Blend 设置一个圆形的按钮
原文:Blend 设置一个圆形的按钮 1)画一个圆形 右击构成控件 3)选择button 当然如果想做成别的控件 都可以 4)我们有了一个button 5)做动画 6)定义触发器 7)定义事件 效果
- [转]ASP.NET Core Web API 最佳实践指南
原文地址: ASP.NET-Core-Web-API-Best-Practices-Guide 转自 介绍# 当我们编写一个项目的时候,我们的主要目标是使它能如期运行,并尽可能地满足所有用户需求. 但 ...
- Dos.ORM修改数据遇到的问题
2019年11月6日,今天使用Dos.ORM进行数据的批量修改,出现修改一条数据造成所有数据相应状态改变的情况,代码如下: 按照一步步调试的方式,排查出原因:生成的orm实体类缺少 主键 的标识,该原 ...
- asp.net core不通过构造方法从容器中获取对象及解决通过这种方法NLog获取对象失败的问题
一般想从容器中获取对象,我们都是通过构造方法获取对象,但有些条件不允许不能通过构造方法获取对象,我们必须单独从容器中单独创建获取找个对象,这样我们就不行把找个容器静态保存起来供全局diaoy 一. 简 ...