python 类的属性与方法_Python类定义及属性与方法说明

类基础

类进阶

Python的类提供了面向对象编程的所有基本功能:

Object类是所有类的父类(不需要明确指定);

类允许继承多个基类(使用逗号分割);

派生类可覆盖基类中任何方法;

类基础

类支持两种操作:

实例化: inst = clsName(…);

属性引用: 使用实例对象或类(类属性)引用对象;

类定义

类通过class定义,里面有属性与方法。

class ClassName:

def funs(self, arg):

# self is the instance of class

@classmethod

def clsFuns(cls, arg):

# cls is the class

@staticmethod

def staticFun(arg):

# 与普通函数类似

类继承

Python支持多继承,多个父类之间通过逗号分割。若是父类中有相同的方法名,而在子类使用时未指定,Python从左到右依次查找父类中是否包含方法(即优先使用排在前面的父类中的方法)。

在多重继承(特别是有菱形继承时),查找关系会更复杂;具体是通过MRO(Method Resolution Order)来解决方法调用二义性问题的;而MRO又是使用的C3算法(拓扑排序+深度优先搜索:依次取出入度为0的节点,取出节点后即把其相关的边去掉,然后递归处理)处理顺序的。

子类中要调用基类中同名方法需:baseCls.fun或super().fun;

class DerivedClassName(Base1, Base2, Base3):

.

变量与可访问性

变量(属性)分类:

类变量:直接定义在类中,为所有类对象共享;通过类名访问clsName.var;

实例变量:每个实例独有的数据(在__init__方法中定义、初始化);通过实例对象访问inst.var;

Python中的可访问性是通过约定来实现的:

私有属性:以两个下划线开始的,__var;

保护属性:以一个下划线开始的,_var;只能自身与子类可访问;

普通属性:以字母等开始的。

类专有方法

Python中通过约定一些专有的方法来增强类的功能:

__init__:构造函数,在生成对象时调用(实例变量也在此函数中定义);

__del__:析构函数,释放对象时使用;

__repr__:打印(若有__str__,则先尝试str),转换;

__setitem__:按照索引赋值;

__getitem__:按照索引取值;

__len__:获取长度,内置函数len()使用;

__cmp__:比较运算;

__call__:函数调用(对象看作一个算子);

__add__:加运算;

__sub__:减运算;

__mul__:乘运算;

__div__:除运算;

__mod__:求余运算;

__pow__:乘方运算;

repr与str:repr()与str()为内置函数,对应类中的__repr__与__str__来处理字符串:

repr对Python(程序员)友好,生成的字符串应可通过eval()重构对象;

str为用户友好,方便用户理解的输出;

print时先查看__str__,若未定义,再查看__repr__;

类进阶

类方法

Python类中有三种方式定义方法:

常规方式:定义实例方法,第一个参数表示实例(一般约定为self);

@classmethod修饰方式:定义类方法,第一个参数表示类(一般约定为cls);

@staticmethod修饰方式:定义静态方法;

以下是三种函数的定义及调用方式:

class MethodTest:

index = 0

def __init__(self):

self.index = -1

def instFun(self, index):

print('instance function:', index, self.index, MethodTest.index)

self.index = index

@classmethod

def classFun(cls, index):

print('class function:', index, cls.index)

cls.index = index

@staticmethod

def staticFun(index):

print('static function:', index, MethodTest.index)

if __name__=="__main__":

mtest = MethodTest()

mtest.instFun(1)  # instance function: -1 0

mtest.classFun(2)  # class function: 0 0

mtest.staticFun(3)  # static function: 3 2

MethodTest.classFun(4)  # class function: 2 2

MethodTest.instFun(mtest, 5)  # instance function: 1 4

MethodTest.staticFun(6)  # static function: 6 4

通过实例对象可以直接调用三类方法;通过类名可以直接调用静态方法与类方法,若要调用实例方法,还需传递一个实例对象。

类属性

通过get/set属性,可以增强对变量的控制,便于后续修改与扩展。但类中的属性(get/set)方法不要手动去实现,应使用@propery来修饰实现:

把一个get方法变成属性,只需增加@propery修饰即可;

@propery本身又创建了另一个装饰器,负责把一个setter方法变成属性赋值:若不增加setter方法,则属性将是只读的。

以下是属性定义的示例:通过@propery定义了count的get属性,然后就可以通过@count.setter来定义set属性了。

class CountProp:

def __init__(self):

self._count=0

@property

def count(self):

return self._count

@count.setter

def count(self, newCount):

self._count = newCount

def __getattr__(self, name):

print('call __getattr__:', name)

value = '{} value for {}'.format(self._index, name)

self._index += 1

setattr(self, name, value)

return value

def __getattribute__(self, name):

print('call __getattribute__:', name)

try:

return super().__getattribute__(name)

except AttributeError:

# setattr(self, name, value)

raise

cPro = CountProp()

print(cPro.count)    # 0

cPro.count = 10

print(cPro.count)    # 10

类中的属性除在类定义(或初始化时)定义外,还可以在任何时候绑定(在给不存在的属性赋值时会自动绑定)。属性的获取与赋值规则为:

先调用getattribute:无论属性是否存在(若属性不存在,需抛出AttributeError异常),因此不能在此方法内引用属性,否则会引起循环递归。因此若要访问属性,则调用super().XXX来避免递归。

属性不存在时(对象的实例字典中查询不到属性时),若类定义了getattr则调用此方法;

当给属性赋值或调用setattr函数时,都会触发setattr方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值