创建类
基本语法
class ClassName:
'类的帮助信息' #类文档字符串
class_suite #类体
eg1:
class Employee:
'所有员工的基类'
count = 0
#类的构造函数
def __init__(self,name,salary): #self,类的实例
self.name = name
self.salary = salary
Employee.count+=1
def displayCount(self):
print("total employee %d" % Employee.count)
def displayEmployee(self):
print("name:",self.name,",salary:",self.salary)
总结
- empCount 变量是一个类变量,它的值将在这个类的所有实例之间共享
- 第一种方法__init__()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法
- self 代表类的实例,self 在定义类的方法时是必须有的,在调用时不必传入相应的参数
eg2:
class Test:
def prt(self):
print(self)
print(self.__class__)
t = Test()
t.prt()
我们看一下执行结果:
总结
从执行结果我们可以看出来,self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类
创建实例对象
对象的实例化,其他编程语言中一般用关键字new,但是在python中,类的实例化类似与调用函数。
eg:
emp1=Employee("chenrun",1000)
如上所示,使用类的名称Employee 来实例化,通过构造函数 init 方法接收参数。
访问属性
和其他语言一样,使用点号。
eg:
emp=Employee("chenrun",1000)
emp.displayEmployee()
emp.displayCount()
我们还可以增加,删除,修改类的属性:
emp.age = 21 #增加了属性并赋值为21
emp.age = 22 #修改属性
del emp.age #删除属性
还有其他方法访问属性吗?
是的,我们还可以使用如下函数的方式来访问属性。
方法 | 作用 |
---|---|
getattr(obj, name[, default]) | 访问对象的属性 |
hasattr(obj,name) | 检查是否存在一个属性 |
setattr(obj,name,value) | 设置一个属性,如果属性不存在,会创建一个新属性 |
delattr(obj, name) | 删除属性 |
eg:
hasattr(emp, 'age') # 如果存在 'age' 属性返回 True
getattr(emp, 'age') # 获取 'age' 属性的值
setattr(emp, 'age', 22) # 添加属性 'age' 值为 8
delattr(emp, 'age') # 删除属性 'age'
python内置类属性
属性名 | 作用 |
---|---|
dict | 类的属性(包含一个字典,由类的数据属性组成) |
doc | 类的文档字符串 |
name | 类名 |
module | 类定义所在的模块 |
bases | 类的所有父类构成元素(包含了一个由所有父类组成的元组) |
使用举例如下:
print("Employee.__doc__:", Employee.__doc__)
print("Employee.__name__:", Employee.__name__)
print("Employee.__module__:", Employee.__module__)
print("Employee.__bases__:", Employee.__bases__)
print("Employee.__dict__:", Employee.__dict__)
输出结果:
python对象销毁
Python 中使用了引用计数这一简单技术来跟踪和回收对象。
当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0时, 它被解释器在适当的时机垃圾回收。
eg:
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, "销毁")
pt1 = Point()
pt2 = pt1
pt3 = pt1
print(id(pt1), id(pt2), id(pt3)) # 打印对象的id
del pt1
del pt2
del pt3
运行结果:
类的继承
python中类的继承与C++类似
类属性与方法
类的私有属性
- __private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问
- 在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数
- 类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用
使用举例:
class Count:
__count = 0
pCount = 0
def count(self):
self.__count += 1
self.pCount +=1
print(self.__count)
counter = Count()
counter.count()
print(counter.pCount)
print(counter.__count) #报错,访问私有成员
那如何访问私有数据呢?
我们可以使用 object._className__attrName( 对象名._类名__私有属性名 )访问属性
还是刚才那个例子,最后代码改为下面的就可以了。
print(counter.pCount)
print(counter._Count__count)
下划线说明
- __foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 __init__()
- _foo: 以单下划线开头的表示的是 protected 类型的变量
- __foo: 双下划线的表示的是私有类型(private)的变量
补充
- 在类的对象生成后,调用含有类私有属性的函数时也可以使用到私有属性
- python 的类和类实例都是可变对象,可以随时给属性赋值,并且在原处修改。
所以在对类属性进行修改时需要特别小心,因为所有的类实例都继承共享类属性,除非实例本身存在和类属性同名的属性 - 补充两个函数:
函数 | 作用 |
---|---|
issubclass() | 布尔函数,判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup) |
isinstance(obj, Class) | 布尔函数,如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true |