python面向对象–类和对象
一. 一些基本概念
- 类:用来描述具有相同的属性和方法的对象的集合,它定义了该集合中每个对象所共有的属性和方法,对象是类的实例
- 类变量:类变量在整个实例化的对象中是公用的,类变量定义在类中且在函数体之外,类变量通常不作为实例变量使用
- 数据成员:类变量和实例变量,用于处理类及其实例对象的相关的数据
- 方法重写:如果从父类继承的方法 不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖,也称为方法的重写
- 局部变量:定义在方法中的变量,只作用于当前实例的类
- 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的
- 继承:即一个派生类继承基类的字段和方法,继承也允许吧一个派生类的对象作为一个基类对象对待,
- 实例化:创建一个类实例,类的具体对象
- 方法:类中定义的函数
- 对象:通过类定义的数据结构实例,对象包括两个数据成员(类变量和实例变量) 和方法
三. python对象销毁(垃圾回收)
python使用了引用计数这个简单技术来跟踪和回收垃圾
在python内部记录着所有使用中的对象各有多少引用
一个内部跟踪变量,称为一个引用计数器
当对象被创建时,就创建了一个引用计数,当这个对象不再需要时,也就是说,这个对象的引用计数变为0时,它被垃圾回收,但是回收不是’立即’的,又解释器在适当的时机,将垃圾对象占用的内存空间回收
a = 40 # 创建对象<40>
b = a # 创建引用,<40>的计数
c = [b] #增加引用,<40>的计数
del a #减少引用<40>的计数
b = 100 #减少引用<40>的计数
c[0] = -1 #减少引用<40>的计数
垃圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况.循环引用指的是,两个对象相互引用,但是没有其他变量引用它们.在这种情况下,仅使用引用计数是不够的.python的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器.作为引用计数的补充,垃圾收集器也会留心被分配的总量很大(及未通过引用计数器销毁的那些)的对象,在这种情况下,解释器会暂停下来,试图清理所有未引用的循环
# -*- coding: utf-8 -*-
class Point:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print(class_name, "ruin.....")
pt1 = Point()
pt2 = pt1
pt3 = pt1
print('pt11111111', id(pt1), id(pt2), id(pt3))
del pt3
'''output
pt11111111 2032686524616 2032686524616 2032686524616
Point ruin.....
'''
四. 类的继承
面向对象的编程带来的主要好处是代码的重用,实现这种重用的方法之一是通过继承机制
通过继承创建的新类称为子类或者派生类,被继承的类称为基类,父类或者超类
类的继承的一些特点:
- 如果在子类这个需要父类的构造方法就需要显式的调用父类的构造方法,或者不重写父类的构造方法,
- 在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量,区别在于类中调用普通函数时并不需要带上self参数
- python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找,(现在本类中查找调用的方法,找不到才到基类中去找)
五. 方法重写
class Parent(object):
"""docstring for Parent"""
def myMethod(self):
print('调用父类方法')
class Child(object):
"""docstring for Child"""
def myMethod(self):
print('调用子类方法')
c=Child()
c.myMethod()
"""output
调用子类方法
"""
基础重载方法
# 以下是一些通用的功能,可以在自己的类重写
__init__(self[,args]) 构造函数,调用方法:obj = className(args)
__del__(self) 析构方法,删除一个对象,调用方法:del obj
__repr__(self) 转化为供解释器读取的形式,调用方法:repr(obj)
__str__(self) 用于转化为适于人阅读的形式,调用方法:str(obj)
__cmp__(self, x) 对象比较,调用方法:cmp(obj,x)
运算符重载
__add__(self)
六. 类属性和方法
类的私有属性:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问,在类内部的方法中使用时self.__private_attrs
类的私有方法:private_method,两个下划线开头,声明该方法为私有方法,不能在类的外部调用,在类的内部调用
self.__private_methods
# print('22222222', j.__secretCount) #直接访问不了
# 用obj._className.__secretvariablename来访问私有属性
print('22222222', j._JustCounter__secretCount)
ps:单下划线 双下划綫 头尾双下划綫说明
__foo__定义的是特殊方法,一般是系统定义名字,类似__init__()之类的
_foo 以单下划线开头的表示的是protected类型的变量,即保护类型只允许本身和子类进行访问,不能用于from module import *
__foo 双下划线的表示的是私有类型的变量,只能是允许这个类本身进行访问了
护类型只允许本身和子类进行访问,不能用于from module import *
__foo 双下划线的表示的是私有类型的变量,只能是允许这个类本身进行访问了
[外链图片转存中...(img-V5n48TiK-1599124345172)]