python渐进-类1

13.1 类的定义和使用

python中使用class关键字来定义类。用类似"class classname():"的语句就可以定义一个新式类。下面的代码是一个简单的类定义:

class IncClass(): n=5 print('initialize') def Incn(self,x): return x+self.n

其中 class IncClass(): 定义了一个类;

n=5是一个类数据成员;

print语句是类代码块;

def语句定义了一个类方法,这个方法的第一个参数是一个self,这个参数指代了一个实例,说明这个类方法必须得通过一个实例来调用。

在使用类的时候一般需要进行实例化后再调用类方法和类变量。示例代码如下:

ic=IncClass()print(ic.Incn(5))

这里IncClass()返回类的实例给ic。

ic.Incn(5)则通过实例ic调用了类方法Incn()。

这段代码的运行结果是

initialize10

13.2 类变量以及实例变量

类变量可以通过类和实例来访问,而实例变量则只能通过实例来访问。

下面的代码演示了使用类和实例来访问一个类变量:

class TestVar(): cvar=9 print(TestVar.cvar)tv=TestVar()print(tv.cvar)

这段代码的运行结果是

99

下面的代码演示了使用类和实例访问一个实例变量:

class TestVar(): def setivar(self): self.ivar=3 tv=TestVar()tv.setivar()print(tv.ivar)print(TestVar.ivar)

这段代码的演示结果为:

3Traceback (most recent call last): File "testclass.py", line 64, in print(TestVar.ivar)AttributeError: class TestVar has no attribute 'ivar'

可以看到使用类访问实例变量的时候发生了错误。类的命名空间并不存在这个变量。

如果类和实例都有一个同名变量,那么在实例中对这个变量赋值,会在实例的命名空间中生成自己的变量,赋值不会影响类变量。下面的演示代码就演示了在实例中对类同名变量进行赋值:

class TestVar(): cvar=4 def setvar(self): self.cvar=3 tv=TestVar()tv.setvar()print(tv.cvar)print(TestVar.cvar)

这段代码的运行结果为:

34

可以看到类变量并没有因为实例变量的修改而改变。

不同的实例如果想要共享同一个类变量的话,那么就不能在实例中进行赋值操作,不然会生成一个实例变量来屏蔽掉类变量。最好使用一个可变变量来绕过这个限制。

下面的代码演示了如何用一个dict来辅助进行多实例的共享变量。

class TestVar(): vardict=dict() vardict['cvar']=4 def setvar(self): self.vardict['cvar']=3 tv=TestVar()tv.setvar()print(tv.vardict['cvar'])print(TestVar.vardict['cvar'])

这段代码的运行结果为:

33

也有人通过实例来获得类,从而可以通过实例来访问类变量。演示代码为:

class TestVar(): cvar=4 def setvar(self): self.__class__.cvar=3 tv=TestVar()tv.setvar()print(tv.cvar)print(TestVar.cvar)

这段代码的运行结果为:

33

这种方法似乎不太被提倡,大概长得比较丑。

13.3 静态方法

之前看到的类方法的定义都是需要通过实例进行调用的。在类中也可以定义静态方法,可以不需要实例化就可以调用。有两种方法可以达到这个效果,一个是使用@classmethod修饰符,一个使用@staticmethod修饰符。示例代码如下:

class TestClass(): @classmethod def cm(cls): print("in classmethod "+cls.__name__) @staticmethod def sm(): print("in staticmethod ")TestClass.cm()TestClass.sm()

以上的代码运行结果为:

in classmethod TestClassin staticmethod

classmethod修饰的函数,第一项参数一定要是cls,也就是类。

而staticmethod修饰的函数可以不带参数。

不过如果staticmethod不带任何类和实例,就无法访问类和实例的变量以及方法。所以,这里使用的时候如果需要访问类和实例的命名空间的话,一般也会自行带上各类参数的。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180626G002N200?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券