• 【Pyton】【小甲鱼】类和对象


    一、类

    定义一个类,例子如下:

     1 class Turtle: #定义一个名为Turtle的类,Python中类型约定以大写字母开头
     2     #属性
     3     color='green'
     4     weight=10
     5     legs=4
     6     shell=True
     7     mouth='大嘴'
     8 
     9     #方法
    10     def climb(self):
    11         print('我正在很努力的向前爬……')
    12     def run(self):
    13         print('我正在飞快的向前跑……')
    14     def bite(self):
    15         print('咬死你咬死你!')
    16     def eat(self):
    17         print('邮的吃,真满足~')
    18     def sleep(self):
    19         print('困了,睡了,晚安,Zzzzz')

    【属性+方法-->实例化对象】

    定义一个对象,调用类中方法:

    1 >>> tt=Turtle()
    2 >>> tt.climb #未调用成功,内存中调用一个实例对象,系统会自动给释放
    3 <bound method Turtle.climb of <__main__.Turtle object at 0x020105B0>>
    4 >>> tt.climb()
    5 我正在很努力的向上爬

    二、

    1.封装:信息隐蔽技术

    1 >>> list1=[2,1,7,5,3]
    2 >>> list1.sort()
    3 >>> list1
    4 [1, 2, 3, 5, 7]
    5 >>> list1.append(9) #append方法我们知道应用后可以达到什么效果但是却不知道它的实现原理,那么这样的方法就是封装起来的
    6 >>> list1
    7 [1, 2, 3, 5, 7, 9]

    2.继承

     1 #创建一个list类型的类
     2 >>> class MyList(list):
     3     pass  #pass的意思,pass是一个占位符,不做任何事情,此类是一个list(列表)
     4 #创建一个list2对象
     5 >>> list2=MyList()
     6 >>> list2.append(5)
     7 >>> list2.append(3)
     8 >>> list2.append(7)
     9 >>> list2
    10 [5, 3, 7]
    11 >>> list2.sort()
    12 >>> list2
    13 [3, 5, 7] #这里实现了排序方法,所以list2继承了Mylist()中的list的方法

    3.多态:不同对象对同一方法相应不同的行动

       【概念理解】奔跑:老鼠、袋鼠、乌龟对于同一个跑的动作都是表现不同的行为的。

     1 >>> class A:
     2     def fun(self):
     3         print('我是小A')
     4 
     5 >>> class B:
     6     def fun(self):
     7         print('我是小B')
     8 
     9         
    10 >>> a=A()
    11 >>> b=B()
    12 >>> a.fun()
    13 我是小A
    14 >>> b.fun()
    15 我是小B

     4.self:相当于不同对象的门牌号。python中调用时候第一个写self是约定俗成的要求(虽然通过同一个类创建的出不同对象,但是通过self可以区别各个对象。)

    调用对象原理:来源于同一个属性和方法,当一个对象被调用,对象会把自身作为第一个参数传给self,接收到self(self作为对象的标志,区别不同对象),python通过对象传过来的self知道是哪个对象在调用方法。

     1 >>> class Ball:
     2     def setName(self,name): #self相当于字典中的key,name相当于字典中的值,所以括号中实际上只传name的值即可。
     3         self.name=name
     4     def kick(self): #调用setName()方法中的self,即取出self.name的值
     5         print('我叫%s,该死的,谁踢我...'%self.name)
     6 
     7         
     8 >>> a=Ball()
     9 >>> a.setName('球A')
    10 >>> b=Ball()
    11 >>> b.setName('球B')
    12 >>> c=Ball()
    13 >>> c.setName('土豆')
    14 >>> a.kick()
    15 我叫球A,该死的,谁踢我...
    16 >>> c.kick()
    17 我叫土豆,该死的,谁踢我...

    5.Python的魔法方法:

    1)__init__(self):构造方法,实例化一个对象时,方法在对象被创建时候自动被调用。不用给对象中各方法中变量分别赋值,只初始化一次赋值即可。例子代码如下:

     1 >>> class Ball:
     2     def __init__(self,name): #应用__init__函数
     3         self.name=name
     4     def kick(self):
     5         print('我叫%s,该死的,谁踢我...'%self.name)
     6 
     7         
     8 >>> b=Ball('土豆')#初始化赋值
     9 >>> b.kick()
    10 我叫土豆,该死的,谁踢我...

    6.共有和私有

    在属性前面加双下划线‘__’可以使属性变成私有属性(原理:其实是Python动了手脚,python会将加双下划线的变量改名为‘_类名__变量名’,所以仍旧可以通过方法进行访问,所以Python类是没有权限控制的,所以实际上是伪私有),那么对象在进行方法调用的时候不可以直接调用该私有属性。可以通过在方法中再利用调用函数来调用,然后外部对象再调用此方法,从而间接的调用出此属性。(下方有举例)

     1 #共有属性:
     2 >>> class Person:
     3     name='小甲鱼'
     4 
     5 >>> p=Person()
     6 >>> p.name
     7 '小甲鱼'
     8 #私有属性,调用报错
     9 >>> class Person:
    10     __name='小甲鱼'
    11 
    12 >>> p=Person()
    13 >>> p.__name
    14 Traceback (most recent call last):
    15   File "<pyshell#75>", line 1, in <module>
    16     p.__name
    17 AttributeError: 'Person' object has no attribute '__name'
    18 #私有属性中写入内部调用方法实现间接调用私有方法
    
    >>> class Person:
        __name='小甲鱼'
        def getName(self):
            return self.__name
    
        
    >>> p=Person()
    >>> p.getName()
    '小甲鱼'
    1 #了解Python私有属性改名原理后进行再次访问尝试
    2 >>> class Person:
    3     __name='小甲鱼'
    4 
    5     
    6 >>> p=Person()
    7 >>> p._Person__name
    8 '小甲鱼'

     二、继承

    1.概念

    1)父类:又名超类、基类、父类

    2)子类:

    2.语法:class 子类名(父类名):

     1 >>> class Parent:
     2     def hello(self):
     3         print('正在调用父类的方法...')
     4 
     5         
     6 >>> class Child(Parent):
     7     pass #类中没有内容可以用pass代替
     8 
     9 >>> p=Parent()
    10 >>> p.hello()
    11 正在调用父类的方法...
    12 >>> c=Child()
    13 >>> c.hello()
    14 正在调用父类的方法...
    15 #如果子类中定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性
    >>> class Child(Parent):
    	def hello(self):
    		print('正在调用子类的方法...')
    
    		
    >>> c=Child()
    >>> c.hello()
    正在调用子类的方法...
    >>> p.hello
    <bound method Parent.hello of <__main__.Parent object at 0x0221FEB0>>
    >>> p.hello()
    正在调用父类的方法...
    

    3.子类中如果重写了父类,那么可以用以下两种方法来调用父类中方法:

    1)调用未绑定的父类方法

    2)使用super函数

     1 import random as r
     2 class Fish:
     3     def __init__(self):
     4         self.x=r.randint(0,10) #x轴坐标
     5         self.y=r.randint(0,10)
     6 
     7     def move(self):
     8         self.x-=1 #鱼每次都向左游
     9         print('我的位置是:',self.x,self.y)
    10 
    11 class Goldfish(Fish):
    12     pass
    13 class Carp(Fish):
    14     pass
    15 class Salmon(Fish):
    16     pass
    17 class Shark(Fish):
    18     def __init__(self):#子类重写了父类的此方法,所以有了下面一句话(Fish.__init__(self))来调用父类
    19         Fish.__init__(self) #1.此处的self为子类shark的self而非父类的self所以称之为未绑定的父类方法
    # 2.(Fish.__init__(self))也可以用super方法来写(super().__init__()),super方法其实更为常见,如果继承多个父类,那么super方法相对更简便
    20 self.hungry=True 21 22 def eat(self): 23 if self.hungry: 24 print('吃货的梦想就是天天有鱼吃') 25 self.hungry=False 26 else: 27 print('太撑了,吃不下了')
    代码F5后运行结果:
    1
    >>> shark=Shark() 2 >>> shark.eat()#调用shark中的eat方法 3 吃货的梦想就是天天有鱼吃 4 >>> shark.move()#调用shark对象中的move方法 5 我的位置是: 1 2 6 >>> shark.move() 7 我的位置是: 0 2 8 >>> shark.move() 9 我的位置是: -1 2 10 >>> Fish.__init__(shark)#调用未绑定父类方法 11 >>> shark.move() 12 我的位置是: 2 10

    4.多重继承:

    1)语法class 子类(父类1,父类2,父类3):

    2)实例:

     1 >>> class Base1:
     2     def foo1(self):
     3         print('我是foo1,我为Base1代言...')
     4 
     5         
     6 >>> class Base2:
     7     def foo2(self):
     8         print('我是foo2,我为Base2代言...')
     9 
    10         
    11 >>> class C(Base1,Base2):
    12     pass
    13 
    14 >>> c=C()
    15 >>> c.foo1()
    16 我是foo1,我为Base1代言...
    17 >>> c.foo2()
    18 我是foo2,我为Base2代言...

     属性名同方法名相同,属性会覆盖方法

    5.绑定

    什么是绑定:Python严格要求方法需要有实例才能被调用,这种限制其实就是Python所谓的绑定概念。

     1 >>> class BB:
     2     def printBB():
     3         print('no zuo no die')
     4         
     5 >>> BB.printBB()
     6 no zuo no die
     7 >>> bb=BB()
     8 >>> bb.printBB() #这句实际上等价于bb.printBB(bb)传进去bb,但是实际上程序中不识别参数,所以无法调用
     9 Traceback (most recent call last):
    10   File "<pyshell#6>", line 1, in <module>
    11     bb.printBB()
    12 TypeError: printBB() takes 0 positional arguments but 1 was given
    13 >>> class CC:
    14     def setXY(self,x,y):
    15         self.x=x
    16         self.y=y
    17     def printXY(self):
    18         print(self.x,self.y)
    19 
    20         
    21 >>> dd=CC() #实例化一个对象dd
    22 >>> dd.__dict__
    23 {}  #目前是一个空的字典
    24 >>> CC.__dict__
    25 mappingproxy({'__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'CC' objects>, 'printXY': <function CC.printXY at 0x0224DD20>, '__dict__': <attribute '__dict__' of 'CC' objects>, 'setXY': <function CC.setXY at 0x0224DCD8>, '__doc__': None})
    26 >>> dd.setXY
    27 <bound method CC.setXY of <__main__.CC object at 0x02240E50>>
    28 >>> dd.setXY(4,5) #dd.setXY(dd,4,5)相当于x设置为4,y设置为5,相当于dd对象绑定了4,5。4,5,传入了dd的空间
    29 >>> dd.__dict__
    30 {'y': 5, 'x': 4}
    31 >>> CC.__dict__ #由于dd已经绑定了4,5,所以CC不会调用到4,5
    32 mappingproxy({'__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'CC' objects>, 'printXY': <function CC.printXY at 0x0224DD20>, '__dict__': <attribute '__dict__' of 'CC' objects>, 'setXY': <function CC.setXY at 0x0224DCD8>, '__doc__': None})
    33 >>> dd.setXY(dd,4,5)
    34 #删除CC类对象,后看dd是否存在
    35 >>> del CC
    36 >>> ee=CC()
    37 Traceback (most recent call last):
    38   File "<pyshell#23>", line 1, in <module>
    39     ee=CC()
    40 NameError: name 'CC' is not defined
    41 >>> dd.printXY() #删除CChou,还可以调用dd的实例对象,类中定义的属性是静态,类被删除,但是其中的属性依旧存在,所以dd仍存在。所以定义类的时候里面尽量定义self.的写法。
    42 4 5
     
  • 相关阅读:
    ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
    大div套多个小div,怎样设置外div的高度自适应?
    搭建高可用rabbitmq集群及spring boot实现集群配置
    linux signal 处理
    freemarker null异常详解及兼容模式
    蓝绿部署、A/B测试以及灰度发布(金丝雀发布)
    动态BGP与静态BGP
    axios与ajax的区别及中文用户指南
    java poi excel给单元格增加批注(包含SXSSF)及设置列类型
    java图片处理(加水印、生成缩略图)等之Thumbnailator库
  • 原文地址:https://www.cnblogs.com/zhuzhubaoya/p/6537333.html
Copyright © 2020-2023  润新知