【Python】-5.Python面向对象


Python是一门面向对象的语言,所以在Python中需要创建类和对象

1. 面向对象

1.1 类的创建

类的定义:

class [类名]:
[语法块]

class EmptyClass:
    pass

1.2 类的使用

class EmptyClass:
    pass


empty = EmptyClass()
print(type(empty)) # <class '__main__.EmptyClass'>

1.3 类的构造方法

在Python中,构造方法就是类的 __init__ 方法,类在实例化时会自动调用 __init__ 方法,用于创建类的实例

class Dog:
    def __init__(self):
        print("汪汪汪!")


dog = Dog() # 汪汪汪!

1.4 类的属性

class Dog:
    def __init__(self, name):
        self.name = name
        self.age = 3


dog = Dog("旺财")
print(dog.name) # 旺财
print(dog.age) # 3

注意:属性必须使用 “self” 加上点的方式赋值,不能直接定义变量。直接定义的变量生命周期只在函数内,函数执行完变量就会被销毁。

class Dog:
    def __init__(self, name):
        self.name = name
        age = 3


dog = Dog("旺财")
print(dog.name) # 旺财

# Dog 没有age这个属性,出现错误: AttributeError: 'Dog' object has no attribute 'age'
print(dog.age)

1.5 类的方法

class Dog:
    def __init__(self, name):
        self.name = name

    def play(self):
        print("汪汪汪!我是", self.name)


dog = Dog("旺财")
dog.play() # 汪汪汪!我是 旺财

1.6 私有属性

为了防止实例随意修改属性,需要用到私有属性。私有属性使用 “__” 作为开头

class Dog:
    def __init__(self, name):
        self.__name = name

    def play(self):
        print("汪汪汪!我是", self.__name)


dog = Dog("旺财")
dog.play() # 汪汪汪!我是 旺财

# 私有属性对外不可见,出现错误: AttributeError: 'Dog' object has no attribute '__name'
print(dog.__name)

提供 set 方法修改私有属性

class Dog:
    def __init__(self, name):
        self.__name = name
        self.__age = None
        print(self.__name, "生成成功")

    def set_age(self, age):
        if not isinstance(age, int):
            print("输入的年龄必须是数字!")
            return False
        if age <= 0:
            print("输入的年龄必须大于0!")
            return False
        self.__age = age

    def play(self):
        print("汪汪汪!我今年", self.__age, "岁")


dog = Dog("旺财") # 旺财 生成成功
dog.set_age("hello") # 输入的年龄必须是数字!
dog.set_age(-20) # 输入的年龄必须大于0!
dog.set_age(3)
dog.play() # 汪汪汪!我今年 3 岁

1.7 私有方法

私有方法只能在内部被调用,实例不能直接调用

class Dog:
    def __say(self, name):
        print(name)

    def play(self):
        self.__say("汪汪汪")


dog = Dog()
dog.play() # 汪汪汪

# 私有方法不能被实例调用,出现错误: AttributeError: 'Dog' object has no attribute '__say'
dog.__say()

2. 继承和多态

面向对象有三大特性: 封装、继承、多态

2.1 继承

注意: Python 支持多重继承,一个类可以有多个父类。

子类的定义如下:

class SubClass(BaseClass1, BaseClass2):
[语法块]

class Animal:
    def __init__(self, name):
        self.name = name

    def play(self):
        print("我是", self.name)


# 继承
class Dog(Animal):
    pass


dog = Dog("旺财")
dog.play() # 我是 旺财

继承有两点需要注意:

  1. 在继承中,如果子类定义了构造方法,则父类的构造方法 __init__ 不会被自动调用,需要在子类中手动调用。
class Animal:
   def __init__(self, name):
       self.name = name

   def play(self):
       print("我是", self.name)


class Dog(Animal):
   def __init__(self):
      print("旺财")

# 父类的构造方法没有被执行,
# 出现错误: TypeError: __init__() missing 1 required positional argument: 'name'
dog = Dog() # AttributeError: 'Dog' object has no attribute 'name'
dog.play() 

正确方式

class Animal:
    def __init__(self, name):
        self.name = name

    def play(self):
        print("我是", self.name)


class Dog(Animal):
    def __init__(self):
        super(Dog, self).__init__("旺财")


dog = Dog()
dog.play() # 我是 旺财
  1. 子类不能继承父类中的私有方法,也不能调用父类的私有方法。
class Animal:
   def __init__(self, name):
       self.__name = name

   def __play(self):
       print("Animal, __play")

   def play(self):
       print("Animal, play")


class Dog(Animal):
   def __init__(self):
       super().__init__("旺财")

   def say(self):
       self.play()
       self.__play()


dog = Dog()
dog.say() 
# Animal, play
# AttributeError: 'Dog' object has no attribute '_Dog__play'

2.2 多态

继承可以帮助我们重复使用代码,但是有时候子类的行为不一定完全和父类一样

2.2.1 子类使用父类实现

class Animal:
    def say(self):
        print("Animal")


class Dog(Animal):
    pass


class Cat(Animal):
    pass


dog = Dog()
dog.say() # Animal

cat = Cat()
cat.say() # Animal

2.2.2 子类自定义方法实现

当子类和父类存在相同的方法时,子类的方法会覆盖父类的方法,这样代码在运行时总是会调用子类的方法

class Animal:
    def say(self):
        print("Animal")


class Dog(Animal):
    def say(self):
        print("Dog")


class Cat(Animal):
    def say(self):
        print("Cat")


dog = Dog()
dog.say() # Dog

cat = Cat()
cat.say() # Cat

2.2.3 判断类的实例

使用内置函数 isinstance
print('--------------------------------------- 2.3 ---------------------------------------')

print(isinstance(dog, Dog)) # True
print(isinstance(dog, Animal)) # True
print(isinstance(cat, Cat)) # True
print(isinstance(cat, Animal)) # True

2.2.4 接收子对象的方法

class Animal:
    def say(self):
        print("Animal")


class Dog(Animal):
    def say(self):
        print("Dog")


class Cat(Animal):
    def say(self):
        print("Cat")


def animal_say(animal: Animal):
    animal.say()


dog = Dog()
cat = Cat()
animal_say(dog) # Dog
animal_say(cat) # Cat

2.3 鸭子类型

在程序设计中,鸭子类型(Ducking Type) 是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口决定的,而是由当前方法和属性的集合决定的

class Dog:
    def say(self):
        print("Dog")


class Cat:
    def say(self):
        print("Cat")


def animal_say(animal):
    animal.say()


dog = Dog()
cat = Cat()

animal_say(dog) # Dog
animal_say(cat) # Cat

3. 类变量和实例变量

3.1 类变量

类变量:不需要实例化就能直接使用,相当于绑定在类上

class Animal:
    name = "动物"


print(Animal.name) # 动物

3.2 实例调用类变量

class Animal:
    name = "动物"


dog = Animal()
cat = Animal()

print(dog.name) # 动物
print(cat.name) # 动物

Animal.name = "哺乳类动物"

print(dog.name) # 哺乳类动物
print(cat.name) # 哺乳类动物

4. 静态方法和类方法

4.1 静态方法

静态方法: 使用 “@staticmethod” 进行装饰。不需要默认参数 “self”,不能调用成员变量和成员方法。和类变量一样,可以直接使用

class Animal:
    name = "动物"

    @staticmethod
    def play():
        print("playing")


Animal.play() # playing

4.2 类方法

类方法: 使用 “@classmethod” 进行装饰。需要一个初始参数cls指向类本身,可以读取和修改类变量

class Animal:
    name = "动物"

    @classmethod
    def play(cls):
        print(cls.name, "playing")


Animal.play() # 动物 playing

文章作者: Soulballad
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Soulballad !
评论
 上一篇
【Python】-6.Python中的错误和异常 【Python】-6.Python中的错误和异常
作为 Python 初学者,在学习 Python 编程时,经常会看到一些报错信息,在前面我们没有提及,这章节我们会专门介绍。 Python 有两种错误很容易辨认:语法错误和异常。 1. 语法错误Python 的语法错误或者称之为解析错,一般
2020-09-10
下一篇 
【Python】-4.Python中的函数 【Python】-4.Python中的函数
在编程中,我们经常要调用相同或者类似的操作,这些相同或者类似的操作是由同一段代码完成的,而函数的出现,可以帮助我们避免重复编写这些代码。函数的作用就是把相对独立的某个功能抽象出来,使之成为一个独立的实体。 例如,我们开发一个支持人与人之间
2020-09-06
  目录