1、场景:
玩过游戏。主人公,进入了一个场景,有10个小怪物是一样的。有攻击力,血(100格)。如果小怪物有多个数值需要管理,小怪物的血量、小怪物出现在屏幕的地点。

可以使用字典来进行记录:

{"blood":100,"location":"10,10"}
[[100,(10,10)]]

10 个小怪物。记住10个小怪物所有的变量在哪里,怎么操作?

写一些函数,来操作这些数据。
函数你实现的时候,你觉得需要实现哪些功能?

10个方法:所有操作的数据的方法

add_blood():
blood+=1

minus_blood():
blood-=1

move():
x-=10
y-=10

类的好处:

1) 把数据封装到实例里面,用同一的规则来进行存取,保证数据的安全和一致性

2)基于类,方便进行扩展 (设计模式)

3)类相当于模板,可以通过构造函数做初始化,快速生成实例

 class soldier(): #小怪物的类

"""小怪物的类,类定义"""

def __init__(self,blood,location_x,location_y):    #构造函数,用来传参,可以无参
        self.blood = blood
        self.location_x = location_x
        self.lcoation_y = location_y

def add_blood(self,num):    #实例方法:方法中有self参数
        if self.blood<=100:
            self.blood+=num
            if self.blood>100:
                self.blood = 100

def minus_blood(self,num):    #实例方法:方法中有self参数
        if self.blood>=0:
            self.blood-=num
            if self.blood<0:
                self.blood = 0

def tell_blood(self):    #实例方法:方法中有self参数
        return self.blood

s1= soldier(100,10,10)    #实例化,传参
s2= soldier(90,10,20)    #实例化,传参
s3= soldier(80,10,30)    #实例化,传参

print(s1.tell_blood())    #调tell_blood函数,输出每个小怪物的血量
print(s2.tell_blood())
print(s3.tell_blood())

 

"""小怪物的类,类定义"""

class soldier():

def __init__(self,blood,location_x,location_y):   #构造函数,用来传参,可以无参

self.blood=blood

self.location_x=location_x

self.location_y=location_y

def add_blood(self,num):                    #实例方法:方法中有self参数

if self.blood<=100:

self.blood+=num

if self.blood>100:

self.blood=100

return self.blood

def minus_blood(self,num):                   #实例方法:方法中有self参数

if self.blood>=0:

self.blood-=num

if self.blood<0:

self.blood=0

return self.blood

def tell_blood(self):                          #实例方法;方法中有self参数

return self.blood

s1=soldier(89,10,10)       #实例化,用模板做出来的东西,传参

s2=soldier(67,10,20)       #实例化,用模板做出来的东西,传参

s3=soldier(23,10,30)       #实例化,用模板做出来的东西,传参

print(s1.add_blood(70))     #调用add_blood函数,给小怪物1加血

print(s2.minus_blood(80))   #调用minus_blood函数,给小怪2物减血

print(s3.add_blood(80))     #调用add_blood函数,黑小怪物3加血

运行结果:

E:\>python a.py

100

0

100

2、类:(相关数据存在一起,并且有一组操作相关数据的方法)

    1)数据(属性)
    2)方法(类里面写的函数叫做方法。)
类比说明:
生产杯子,杯子的模具(类),可以设定不同的参数来生产杯子。
设定好不同的参数(通过构造函数传参),生产出具体的杯子(实例化)。
类:soldier
实例化:传入不同的参数(调用构造函数)
s1
s2
s3

3、批量生成实例化对象

import math
class circle(object):    #object可写可不写

def __init__(self,radius):
        self.radius = radius    #radius这个变量在构造函数里,是一个局部变量,走出构造函数,radius这个变量是不能使用的。如果要使用该变量值,需要存在一个带self.的变量中,才能在其他的类方法中使用该值
    def get_area(self):
        return math.pi*self.radius*self.radius    #self.XXX称作实例变量

def get_perimeter(self):
        return 2*math.pi*self.radius

for i in range(1,6):
    a= circle(i)
    print(a.get_area())
    print(a.get_perimeter())

#self.xxxx实例变量
#在类里面定义的函数叫做方法

def add():#函数
  return a+b

 

4、类:封装了数据,和操作数据的规则,保证数据的安全。

1. 如果用列表存储数据:

 a=[1,2,3]  #只存正数的列表
 1)也可使用函数来限制输入的数字
def set(a,index,new_value):
    if new_value>=0:     #当输入的值>=0时,新值会替代原始数据
        a[index] = new_value

set(a,0,100)      #新输入的值为100大于0,替换a[0]的值    
print(a)
set(a,0,-50)    #新输入的值为-50,小于0.不会替换a[0]的值
print(a)

2)但是无法限制别人修改值

a[0]=-50      
print(a)

 

2. 用类来实现限制修改输入负数

 class positive_num_list(object):

def __init__(self,a):
        self.__value = a    #将输入的列表值赋值给实例变量

def set(self,index,value):
        if value<0:    #当输入的值为负数时,什么都不做
            return
        self.__value[index] = value    #当输入的不为负数时,替换a中的数据;两个下划线是私有变量,除了类中的实例方法可以访问,外部不可以直接访问和修改
    def get(self):
        return self.__value    #读取列表中的值

p= positive_num_list([1,2,3,4])    #a=[1,2,3,4]

p.__value[0]=-100    #类保护了数据被修改

运行结果:

AttributeError: 'positive_num_list' object has no attribute '__value'    

print(p.get())    #结果:[1, 2, 3, 4]

p.set(1,50)    #试图替换a[1]的值为50
print(p.get())   #读取替换后的值,结果:[1, 50, 3, 4]

print(set([1,1,2,2]))

结果:{1, 2}  #set集合去重

class positive_num_list(object):

def __init__(self,a):

self.value=a                      #实例变量没有双下划线

def set(self,index,value):

if value<0:

return

self._value[index]=value

def get(self):

return self._value

p=positive_num_list([1,2,3,4])

p.value[0]=-8                             #尝试修改数值

print(p.get())

运行结果:

E:\>python a.py

[-8, 2, 3, 4]                           #数据依然被是修改成功,说明私有变量的重要性

3.用类来限制修改半径:

 import math
class circle(object):

def __init__(self,radius):
        if radius<=0:    #当输入值是<=0的数时,将输入值重新赋值为1
            self.radius = 1
        else:

            self.radius = radius

def modify_radius(self,radius):    #可以定义一个方法,限制输入值是负数
        if radius<0:
            self.radius = abs(radius)
        elif radius==0:
            self.radius = 1

def get_area(self):
        return math.pi*self.radius*self.radius

def get_perimeter(self):
        return 2*math.pi*self.radius

c=circle(-1)    #走构造函数的程序
print(c.get_area())
c.modify_radius(-2)    #调用modify_radius方法
print(c.get_area())

 
5、self
 class P:

def __init__(self,value): #构造方法,初始化的
        self.value = value     #value局部变量,self.value叫做实例变量
p =P(10)
print(p.value)
p.value=-10
print(p.value)

 
 
 class P:

def __init__(self,value): #构造方法,初始化的
        self.__value = value     #value局部变量,self.value叫做实例变量
p =P(10)
print(p.__value)    #私有变量

 
 
 class P:

def __init__(self,value): #构造方法,初始化的
        self.__value = value     #value局部变量,self.value叫做实例变量
    def get(self):              #实例方法
        return "***:"+str(self.__value)
    def set(self,value):           #实例方法
        if isinstance(value,(int,float)):
            self.__value = value
        return None

p =P(10)
print(p.get())    #私有变量
p.set("a")
print(p.get())    #私有变量
p.set(-5)
print(p.get())    #私有变量

 
 
 class P:

def __init__(self,value): #构造方法,初始化的
        self.__value = value   #value局部变量,self.value叫做实例变量
    def get(self):  #实例方法
        return "***:"+str(self.__value)
    def set(self,value):  #实例方法
        if isinstance(value,(int,float)):
            self.__value = value
        return None

p1 =P(1)
p2 =P(2)
p3 =P(3)

内存中的位置:A
P:类变量
类定义的方法

类中所有定义的方法,类变量,只有一份

实例在内存中:有0个,1个或多个
内存中的位置:b
p1的实例:self.__value=1

内存中的位置:c
p2的实例:self.__value=2

内存中的位置:d
p3的实例:self.__value=3

p1.get()--->p1的实例调用get的方法:调用的时候,会把内存位置b发送给类定义的方法P.get
self:是一个方法的参数,该参数传的值是内存b的位置

get方法从内存b的位置找到__value值,然后执行方法中的代码。

但是定义的时候:def get(self),有self参数,调用的时候p1.get(),没有self.

实际get拿到了self的地址(该方法在内存中的位置b),找到了__value值

如果不把self的值传过去,找不到value所在的内存地址,方法执行失败

self传递的是某个实例的地址。实例地址里面的所有变量都可以在方法中进行使用。

 
 p3.set(1,2) #p3的地址传递给了self,1-》value,2是多余的。。
TypeError: set() takes 2 positional arguments but 3 were given
 
 
类中方法参数包含self的方法:实例方法
每个实例方法,只能操作本实例中的实例变量。

变量前面带有self.的叫做实例变量,可以在多个方法中访问,实例变量都存在对应的实例所在的内存地址中。

如果不加self.的叫做局部变量,不能跨方法访问

class P(object):

def __init__(self,value):        #构造方法,初始化的

value1=value           #value1和value局部变量,不能跨方法访问

def get(self):

return value1          #在这个方法中返回value1

p1=P(1)

print(p1.get())

运行结果

E:\>python a.py

Traceback (most recent call last):

File "a.py", line 10, in <module>

print(p1.get())

File "a.py", line 7, in get

return value1

NameError: name 'value1' is not defined  #value1未定义

总结:
 
 类:
   1 可以封装数据,制定数据的存储规则,保证数据的安全
   2 类相当于模板,可以通过构造函数做初始化,快速生成实例
   3 基于类,可以进行扩展。(设计模式)
   4 内存中存储的类变量和方法,只有一份。每个类的实例,都在内存中有一个地址(类产生的实例可以有0个、1个或多个)
   5 类中定义的实例方法(方法中有self参数),可以操作每个实例中封装的变量
   6 实例变量(self.开头的)可以在不同的实例方法中被访问。实例变量都存在对应的实例所在的内存地址中。
   7 __变量是私有变量,除了类中的实例方法可以访问,外部不可以直接访问和修改。
 
 
 
 
 
 

python入门(十二):面向对象的更多相关文章

  1. Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理)

    Python进阶(十六)----面向对象之~封装,多态,鸭子模型,super原理(单继承原理,多继承原理) 一丶封装 , 多态 封装:            将一些东西封装到一个地方,你还可以取出来( ...

  2. Python进阶(十五)----面向对象之~继承(单继承,多继承MRO算法)

    Python进阶(十五)----面向对象之~继承 一丶面向对象的三大特性:封装,继承,多态 二丶什么是继承 # 什么是继承 # b 继承 a ,b是a的子类 派生类 , a是b的超类 基类 父类 # ...

  3. 初学 Python(十二)——高阶函数

    初学 Python(十二)--高阶函数 初学 Python,主要整理一些学习到的知识点,这次是高阶函数. #-*- coding:utf-8 -*- ''''' 话说高阶函数: 能用函数作为参数的函数 ...

  4. Python进阶(十二)----re模块

    Python进阶(十二)----re模块 一丶re模块 ​ re模块是python将正则表达式封装之后的一个模块.正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行. #正则表达式: ...

  5. Python 入门 之 初识面向对象

    Python 入门 之 初识面向对象 1.初识面向对象编程 (核心--对象) (1)观察以下代码: # 面向过程编程 s = "alexdsb" count = 0 for i i ...

  6. Android入门(十二)SQLite事务、升级数据库

    原文链接:http://www.orlion.ga/610/ 一.事务 SQLite支持事务,看一下Android如何使用事务:比如 Book表中的数据都已经很老了,现在准备全部废弃掉替换成新数据,可 ...

  7. Python 第十二篇:HTML基础

    一:基础知识: HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,他是一种制作万维网页面标准语言(标记).相当于定义统一的一套规则,大家都来遵守他,这样就可 ...

  8. Python学习札记(三十二) 面向对象编程 Object Oriented Program 3

    参考:访问限制 NOTE 1.eg. #!/usr/bin/env python3 class Student(object): """docstring for Stu ...

  9. python入门(二十讲):爬虫

    什么是爬虫? 按照一定的规则,自动地抓取万维网信息的程序或脚本. 爬虫目的: 从网上爬取出来大量你想获取类型的数据,然后用来分析大量数据的类似点或者其他信息来对你所进行的工作提供帮助. 为什么选择py ...

  10. Python入门 (二)

    本文是个人python学习笔记,学习资料为廖雪峰python教程,如需更多内容,请移步廖老师官方网站. 一 函数式编程Functional Programming 函数式编程允许把函数本身作为参数传入 ...

随机推荐

  1. PowerShell ISE:Windows Server 2008 R2默认不安装

    PowerShell ISE:Windows Server 2008 R2默认不安装,需要手动安装,在PowerShell运行如下两段脚本: Import-Module ServerManager A ...

  2. vue 中 相同的路由不会跳转,更改路由的办法

    vue 开发的项目,路由跳转的时候,是相同的路由是不会跳转,页面也不会有更新的 有时候 必须要跳转怎么办, 更改一个参数,num,一直在改变.就可以进入了. this.$router.push({ p ...

  3. 在windows下安装、配置、运行PostgreSQL【转】

    安装PostgreSQL 在Windows下的安装就位无脑安装,选择好安装路径就好了,我的安装目录为D:\PostgreSQL\10,需要注意一下几点: 安装过程中需要一个数据库的目录,我的为D:\P ...

  4. pandas模块实现小爬虫功能-转载

    pandas模块实现小爬虫功能 安装 pip3 install pandas 爬虫代码 import pandas as pd df = pd.read_html("http://www.a ...

  5. JSONObject 转List 强制类型转换错误

    JSONArray arr=(JSONArray)map.getOrDefault("data","");List<DHD> data=JSONOb ...

  6. Python import与from import使用及区别介绍

    Python程序可以调用一组基本的函数(即内建函数),比如print().input()和len()等函数.接下来通过本文给大家介绍Python import与from import使用及区别介绍,感 ...

  7. Excel 2016 密码保护破解

    Excel 2016的密码保护可以区分为几个: 文件密码保护(Excel中叫做工作簿保护) 文件打开权限密码 文件修改权限密码 工作表保护 关于各个保护密码的设置方式请查阅其他资料,我的情况是之前自己 ...

  8. java 中的强制转换

    强制转换分两种,一种是基础类型强制转换(Type Conversion),一种是引用类型强制转换(Class Casting):

  9. 正确的学python方式

    首先呢,和其他的各种学习都一样,你一定要明白你学习的目标是什么.有的人想要通过学习Python,转行成程序员,实现行业上的转变:有的人希望通过学习Python,在现有的岗位上提升自己:当然也有很多人只 ...

  10. OGG-01091 Unable to open file "./dirdat/cs001481" (error 2, No such file or directory)

    记一次ogg报错ogg-01091的处理过程 现场有一套RAC数据库的服务器异常重启,其中一个节点上部署了OGG,机器开机之后,发现OGG所有应用进程abended状态,查看日志,发现报错如下图: 分 ...