MST

星途 面试题库

面试题:Python类属性默认值的动态设定

假设有一个类`Circle`,需要一个类属性`pi`,其默认值为3.14,但要求在程序运行时,根据用户输入决定是否更新`pi`的值为`math.pi`(需导入`math`模块)。请写出实现该功能的代码,并阐述这样做可能会带来的问题以及如何避免。
17.1万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试
import math


class Circle:
    pi = 3.14

    @classmethod
    def update_pi(cls):
        user_input = input("是否更新pi的值为math.pi?(y/n)")
        if user_input.lower() == 'y':
            cls.pi = math.pi


可能带来的问题

  1. 输入合法性问题:用户输入可能不是 yn,这会导致程序逻辑异常。
  2. 线程安全问题:如果在多线程环境下运行,不同线程同时调用 update_pi 方法可能导致数据竞争,使得 pi 的值更新不一致。
  3. 代码可读性和维护性:在类中直接处理用户输入,破坏了类的单一职责原则,使得类既负责数据和行为定义,又负责输入交互,不利于代码的复用和维护。

避免方法

  1. 输入合法性检查:在获取用户输入后,增加对输入内容的合法性判断。如果输入不是预期值,提示用户重新输入。
import math


class Circle:
    pi = 3.14

    @classmethod
    def update_pi(cls):
        while True:
            user_input = input("是否更新pi的值为math.pi?(y/n)").lower()
            if user_input == 'y':
                cls.pi = math.pi
                break
            elif user_input == 'n':
                break
            else:
                print("输入无效,请输入y或n。")


  1. 线程安全:使用锁机制(如 threading.Lock)来确保在更新 pi 值时不会出现数据竞争。
import math
import threading


class Circle:
    pi = 3.14
    lock = threading.Lock()

    @classmethod
    def update_pi(cls):
        with cls.lock:
            while True:
                user_input = input("是否更新pi的值为math.pi?(y/n)").lower()
                if user_input == 'y':
                    cls.pi = math.pi
                    break
                elif user_input == 'n':
                    break
                else:
                    print("输入无效,请输入y或n。")


  1. 分离职责:将用户输入部分从类中分离出来,使类专注于其核心功能,即数据和行为的定义。
import math


class Circle:
    pi = 3.14

    @classmethod
    def update_pi(cls):
        cls.pi = math.pi


def user_interaction():
    while True:
        user_input = input("是否更新pi的值为math.pi?(y/n)").lower()
        if user_input == 'y':
            Circle.update_pi()
            break
        elif user_input == 'n':
            break
        else:
            print("输入无效,请输入y或n。")


if __name__ == "__main__":
    user_interaction()