Python 类进阶

类进阶

受苦的人,没有悲观的权力 – 尼采

类属性和类方法

之前对象属性和对象方法是绑定在对象这个层次上的,也就是说需要先创建对象,然后才能使用对象的属性和方法


对象 =()

对象.属性
对象.方法()

除此之外,还有一种绑定在类这个层面的属性和方法,叫做类属性和类方法.使用类属性和类方法,不用创建对象,直接通过类来使用

类属性和类方法的使用方式:

.属性
类.方法()

类属性的定义

  • 只要将属性定义在类之中方法之外即可

class Char:
    属性2 =def 某方法():
     pass
  • 举个例子

class Char:
  letters = 'ABCDEFG'
  digits = '0123456789'

这里定义了类 Char 有两个类属性,这两个类属性分别包含所有大写字母和所有数字.可以通过类名来使用这两个类属性,无须创建对象


class Char:
    letters = 'ABCDEFG'
    digits = '0123456789'


print(Char.letters)
print(Char.digits)

# 结果
# ABCDEFG
# 0123456789

类方法的定义

定义类方法时,需要在方法前面加上装饰器,装饰器以后会说明现在只要知道用法即可


class:

   @classmethod
 def 类方法(cls):
    pass

类方法的第一个参数通常名为 cls,表示当前这个类本身.我们可以通过该参数来引用类属性,或者类中其他类方法

类方法中可以使用该类的类属性,但不能使用该类的对象属性.因为类方法属于类,而对象属性属于对象,使用类方法的时候可能对象还没有被创建出来

  • 举例子

import random


class Char:
    letters = 'ABCDEFG'
    digits = '0123456789'
    @classmethod
    def random_letter(cls):
        return random.choice(cls.letters)

    @classmethod
    def random_digits(cls):
        return random.choice(cls.digits)


result1 = Char.random_letter()
result2 = Char.random_digits()

print(result1)

print(result2)

# 结果 随机
# F
# 3

静态方法

与类方法有点相似的是静态方法,静态方法也可以直接通过类名来调用,不必创建对象.不同在于类方法的第一个参数是类自身(cls) 而静态方法没有这样的参数.

如果方法需要和其他类属性或者类方法交互,那么可以将其定义为类方法.如果方法无需和其他类属性或者类方法交互,那么可以将其定义成静态方法

定义静态方法时候,需要在方法的前面加上装饰器@staticmethod


class:
   @staticmethod
   def 静态方法():
    pass
  • 举例

import random


class Char:
    letters = 'ABCDEFG'
    digits = '0123456789'
    @classmethod
    def random_letter(cls):
        return random.choice(cls.letters)

    @staticmethod
    def random_char(string):
        if not isinstance(string, str):
            raise TypeError('需要传递字符参数')
        return random.choice(string)


result1 = Char.random_letter()
result2 = Char.random_char('哈黑白')

print(result1)

print(result2)

# 结果
# G 白

私有属性和方法

  • 有的时候我们不希望把信息暴露除去,只希望在类中使用,不能被类的外部所访问

  • 我们可以在属性或者方法的名称上用__(两个下划线)开头即可


import random


class Char:
    __letters = 'ABCDEFG'
    __digits = '0123456789'
    @classmethod
    def random_letter(cls):
        return random.choice(cls.__letters)

    @staticmethod
    def random_char(string):
        if not isinstance(string, str):
            raise TypeError('需要传递字符参数')
        return random.choice(string)


result1 = Char.__digits
result2 = Char.__letters

print(result1)

print(result2)

# 结果就直接报错了
  • 可是类中的方法却能直接使用

import random


class Char:
    __letters = 'ABCDEFG'
    __digits = '0123456789'
    @classmethod
    def random_letter(cls):
        return random.choice(cls.__letters)

    @staticmethod
    def random_char(string):
        if not isinstance(string, str):
            raise TypeError('需要传递字符参数')
        return random.choice(string)


# result1 = Char.__digits
# result2 = Char.__letters
# print(result1)
# print(result2)
result3 = Char.random_letter()

print(result3)

像这样以__(两个下划线)开头的属性,我们称为私有属性.顾名思义它是私有的,不能在类的外部使用

特殊方法

类中以__开头并以__结尾的方法是特殊的方法,特殊的方法有特殊的用途,他们可以直接调用,也可以通过一些内置函数或操作符来间接调用,如__init__(),__next__()

特殊方法有很多,我们简单说几个

(1) __init__()

init 是一个非常典型的特殊方法,它用于对象的初始化,在实例化类的过程中被自动调用

(2)__next__()

next() 在迭代器中表示能生成下一个值.

(3) __len__()

len 函数就是获取容器的长度

(4) __str__()

在使用 print()函数将自动调用 str 方法


class A:
  def __str__(self):
      return '这是A的对象'

(5) __getitem__()

诸如列表,元素,字符串这样的序列,我们可以通过索引的凡是来获取其中的元素,这背后 getitem()起作用


'abc'.__getitem__(2)

## 结果 c

继承

如果想基于一个现有的类获取其全部能力,并在此基础上获取一个更强大的类。此时应该使用类的继承.被继承的类叫做父类,继承者叫做子类


class 父类:

    父类的实现

class 子类(父类):

    子类的实现
  • 例如

class A :
  def __init__(self):
    self.apple = 'apple'
  def haveapple(self):
    print('hava' ,self.apple)

class B(A):
    def who(self):
       print('这就是子类')


b = B()
b.who()  # 这就是子类
b.haveapple()  # have apple
b.apple  # apple

子类 B 当中也可以自己定义自己的属性


class B(A):

    def __init__(self):
       super().__init__()
       self.banana = 'banana'

b =B()
b.banana   # 结果banana

我们在 B 中定义了 init 方法并在其中定义了 B 自己的属性 banana

super().__init__()这句代码的意思就是子类初始化的同时初始化父类

super()用在类的方法中时,返回父类对象

  • 子类要是出现和父类同名的方法的话,子类会覆盖父类的同名方法

class A:
   def __init__(self):
       self.apple = 'apple'
   def have(self):
        print('I hava an', self.apple)

class B(A):
    def __init__(self):
         super().__init__()
         self.banana = 'banana'
    def have(self):
       print('I hava an', self.banana)

b = B()
b.have() # 结果 I have an banana

继承链

子类可继承父类,同样的父类也可以继承自己的父类,如此一层一层继承下去


class A:
    def have(self):
       print('I hava an apple')

class B(A):
    pass

class C(B):
    pass

c = C()
c.have() # I have an apple
  • 如果要判断一个类是否是另一个类的子类,可使用内置函数 issubclass()

issubclass(C,A)

# True

issubclass(B,A)

# True

issubclass(C,B)

# True

多继承

子类可以同时继承多个父类

定义时子类后面加上括号并写人多个父类


class A:
      def get_apple(self):
         return 'apple'

class B:
     def get_banana(self):
          return 'banana'

class C(A, B):
     pass

C= C()
c.get_apple()
c.get_banana()
# C 同时具有了A,和B的能力

文章作者: 雾烟云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 雾烟云 !
  目录