《小甲鱼零基础入门学习Python》自学笔记(五)—— 类和对象

类和对象

一、类和对象的简单介绍

对象 = 属性 + 方法

定义一个类class关键字
Python中的类名约定以大写字母开头。

面向对象的特征(Object Oriented):
a.封装:信息隐蔽技术
b.继承:子类自动共享父类之间数据和方法的机制
c.多态:不同对象对同一方法响应不同的行动

二、面向对象编程

(1)self:Python的self相当于C++的this指针

由同一个类可以生成无数个对象,这些对象长得都很相似,因为他们都是来源于同一个类的属性和方法,当一个对象的方法被调用的时候,对象会将自身作为第一个参数传给self参数,接收到self的时候,Python就知道是哪一个对象在调用方法了。

eg:

>>> class Ball:
	def setName(self, name):
		self.name = name
	def talk(self):
		print('我是%s' % self.name)


>>> a = Ball()
>>> a.setName('足球')
>>> b = Ball()
>>> b.setName('篮球')
>>> a.talk()
我是足球
>>> b.talk()
我是篮球

(2)Python的魔法方法之一

__init__(self)
__init__(self, param1, param2...)

在类实例化后,会自动调用__init__(self)方法。

eg:

>>> class Ball:
	def __init__(self, name):
		self.name = name
	def talk(self):
		print('我是%s' % self.name)

		
>>> a = Ball('羽毛球')
>>> a.talk()
我是羽毛球

(3)公有和私有

默认来说,对象的属性和方法都是公有的,可以通过“.”操作符进行访问。
在Python中定义私有变量只需要在变量名或函数名前加上“__”两个下划线,那么这个函数或变量就会为私有的了。

三、继承

子类可以继承父类的属性和方法

1、定义一个子类:

class DerivedClassName(BaseClassName):

BaseClassName:父类、基类或超类
DerivedClassName:子类

eg:

import random as r

class Fish:
    def __int__(self):
        self.x = r.randint(0, 10)
        self.y = r.randint(0, 10)

    def move(self):
        self.x -= 1
        print('我的位置是:', self.x, self.y)

class Goldfish(Fish):
    pass

class Carp(Fish):
    pass

class Salmon(Fish):
pass

运行:

>>> fish = Goldfish()
>>> fish.__int__()
>>> fish.move()
我的位置是: 7 9

注意:
如果子类中定义与父类同名的方法或者属性,则会自动覆盖父类对应的方法或属性。

2、当子类中与父类同名的方法或属性覆盖掉父类中的方法或属性,但又想引用父类中的方法或属性时,我们可以采用以下两种方法:

a.调用未绑定的父类方法
b.使用super函数

eg:调用未绑定的父类方法

import random as r

class Fish:
    def __init__(self):
        self.x = r.randint(0, 10)
        self.y = r.randint(0, 10)

    def move(self):
        self.x -= 1
        print('我的位置是:', self.x, self.y)

class Goldfish(Fish):
    pass

class Carp(Fish):
    pass

class Salmon(Fish):
    pass

class Shark(Fish):
    def __init__(self):
        Fish.__init__(self)
        self.hungry = True

    def eat(self):
        if self.hungry == True:
            print('我饿了!我要吃饭!')
            self.hungry = False
        else:
            print('我好撑!吃不下了!')

eg:使用super函数

import random as r

class Fish:
    def __init__(self):
        self.x = r.randint(0, 10)
        self.y = r.randint(0, 10)

    def move(self):
        self.x -= 1
        print('我的位置是:', self.x, self.y)

class Goldfish(Fish):
    pass

class Carp(Fish):
    pass

class Salmon(Fish):
    pass

class Shark(Fish):
    def __init__(self):
        super().__init__()
        self.hungry = True

    def eat(self):
        if self.hungry == True:
            print('我饿了!我要吃饭!')
            self.hungry = False
        else:
            print('我好撑!吃不下了!')

四、多重继承

定义一个子类:

class DerivedClassName(Base1, Base2, Base3):

注意:尽量避免使用多重继承!

五、组合

把类的实例化放在新的类里面,就把旧的类组合进去了。

eg:

class Turtle:
    def __init__(self, x):
        self.num = x

class Fish:
    def __init__(self, y):
        self.num = y

class Pool:
    def __init__(self, x, y):
        self.turtle = Turtle(x)
        self.fish = Fish(y)

    def print_num(self):
        print('水池中有%d只乌龟,%d条鱼。' % (self.turtle.num, self.fish.num))

运行:

>>> p = Pool(1, 5)
>>> p.print_num()
水池中有1只乌龟,5条鱼。

六、类、类对象和实例对象

>>> class C:
	count = 0

	
>>> a = C()
>>> b = C()
>>> c = C()
>>> a.count
0
>>> b.count
0
>>> c.count
0
>>> c.count += 10
>>> c.count
10
>>> a.count
0
>>> b.count
0
>>> C.count += 100
>>> a.count
100
>>> b.count
100
>>> c.count
10

在这里插入图片描述

如果实例化对象的属性和类的方法名相同,属性会覆盖掉方法。

注意:
1.不要试图在一个类里边定义出所有能想到的特性和方法,应该利用继承和组合机制来进行扩展。
2.用不同的词性命名,如属性名用名词,方法名用动词。

七、绑定

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

>>> class CC:
	def setXY(self, x, y):
		self.x = x
		self.y = y
	def printXY(self):
		print(self.x, self.y)

		
>>> dd = CC()
>>> dd.__dict__
{}
>>> CC.__dict__
mappingproxy({'__module__': '__main__', 'setXY': <function CC.setXY at 0x041B0FA0>, 'printXY': <function CC.printXY at 0x041B8028>, '__dict__': <attribute '__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None})

未给实例对象dd赋值时,dd的属性是一个空字典。类对象CC的属性中包含实例化对象的属性,不显示类属性和特殊属性。

>>> dd.setXY(4, 5)
>>> dd.__dict__
{'x': 4, 'y': 5}
>>> CC.__dict__
mappingproxy({'__module__': '__main__', 'setXY': <function CC.setXY at 0x041B0FA0>, 'printXY': <function CC.printXY at 0x041B8028>, '__dict__': <attribute '__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None})

给实例对象dd赋值后,dd的属性仅属于dd对象,类对象CC中不存在xy

>>> del CC
>>> ee = CC()
Traceback (most recent call last):
  File "<pyshell#15>", line 1, in <module>
    ee = CC()
NameError: name 'CC' is not defined
>>> dd.printXY()
4 5

删掉类实例CC,不能再实例化类CC,但实例对象dd依旧能调用类CC中的方法。因为类中定义的属性和方法都是静态变量,就算类对象被删除了,它们依然是存放在内存中的。只有当程序被退出的时候,这个变量才会被释放。

八、一些相关的BIF

1、issubclass(class, classinfo)

检查class是否是classinfo的一个子类,是,返回True,否,返回False
注意:
1.这种检查是非严格性的检查,一个类被认为是其自身的子类。
2.classinfo可以是类对象组成的元组,只要class是其中任何一个候选类的子类,则返回True。如果第二个参数不是类或者由类对象组成的元组,会抛出一个TypeError异常。

2、isinstance(object, classinfo)

检查实例对象object是否属于类classinfo,是,返回True,否,返回False
注意:
1.classinfo可以是类对象组成的元组,只要object是其中任何一个候选类的实例对象,则返回True
2.如果第一个参数不是对象,则永远返回False
3.如果第二个参数不是类或者由类对象组成的元组,会抛出一个TypeError异常。

3、hasattr(object, name)

测试对象object是否有指定的属性namename为字符串格式。

4、getattr(object, name[, default])

返回对象object中指定的属性name的值,default是当属性name不存在时返回的参数。

5、setattr(object, name, value)

设置对象object中指定的属性name的值为value,如果属性name不存在,会新建一个属性并给它赋值。

6、delattr(object, name)

删除对象object中指定的属性name,如果属性name不存在,则抛出AttributeError异常。

7、property(fget=None, fset=None, fdel=None, doc=None)

通过属性设置属性。

eg:

>>> class C:
	def __init__(self, size=10):
		self.size = size
	def getSize(self):
		return self.size
	def setSize(self, value):
		self.size = value
	def delSize(self):
		del self.size
	x = property(getSize, setSize, delSize)

	
>>> c = C()
>>> c.x				# 调用 property第一个参数getSize方法
10
>>> c.x = 20			# 调用 property第二个参数setSize方法
>>> c.x
20
>>> del c.x			# 调用 property第三个参数delSize方法
>>> c.x
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    c.x
  File "<pyshell#11>", line 5, in getSize
    return self.size
AttributeError: 'C' object has no attribute 'size'
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值