Python:从不同的文件导入实例方法是否不符合Python规范?

Python:从不同的文件导入实例方法是否不符合Python规范?,python,Python,在处理大型项目时,让一个类的实例方法从不同的文件导入是不合适的?我正在从事一个大型项目,我们正在导入许多函数作为实例方法,我想知道这是否是一个好的实践。对于一个较小的例子,我们有两个不同的文件。一个包含主类,另一个包含辅助函数 时间到驱动器。py class TimeToDrive: from helper_functions import calculate, check_variables, get_stats def __init__(self, avg_traffic_

在处理大型项目时,让一个类的实例方法从不同的文件导入是不合适的?我正在从事一个大型项目,我们正在导入许多函数作为实例方法,我想知道这是否是一个好的实践。对于一个较小的例子,我们有两个不同的文件。一个包含主类,另一个包含辅助函数

时间到驱动器。py

class TimeToDrive:
    from helper_functions import calculate, check_variables, get_stats

    def __init__(self, avg_traffic_flow, length, speed, number_of_runs):
        self.avg_traffic_flow = avg_traffic_flow
        self.length = length
        self.speed = speed
        self.number_of_runs = number_of_runs

        self.check_variables()
        self.calculate()
        self.get_stats()
helper_functions.py

from random import random, uniform

import pandas as pd



def check_variables(self):
    if self.speed < 25 or self.speed > 80:
        raise Exception(f"Average speed limit of {self.speed}mph is not realistic")
    if self.avg_traffic_flow > 1 or self.avg_traffic_flow < 0:
        raise Exception(f"Average traffic flow must be between 0 and 1 (1 is best traffic, 0 is worst)")
    if self.length < 0:
        raise Exception(f"Length of route can not be less than zero")


def calculate(self):
    self.runs = pd.DataFrame(columns=['time needed', 'average speed'])

    for _ in range(self.number_of_runs):
        c = self.avg_traffic_flow
        x = random()
        exponent = uniform(1, 10)
        traffic_flow = c * x**(1/exponent) + (1-c) * x**exponent  # Function to calculate traffic flow
        speed = round(self.speed * traffic_flow, 2)
        time_needed_hours = self.length / self.speed
        self.runs = self.runs.append({'time needed': time_needed_hours, 'average speed': speed}, ignore_index=True)


def get_stats(self):

    self.avg_time = self.runs['time needed'].mean()
    self.avg_speed = self.runs['average speed'].mean()
根据计算交通流的函数返回驾驶路线所需的不同时间。示例输出为

0.35 hours
我理解,对于这个特定的示例,将函数作为实例方法导入没有多大意义。将函数分离到类中会更具可读性和python风格。但是,这种方法有什么问题吗?因为对于非常非常大的项目,从一堆不同的文件导入一堆不同的函数会变得很麻烦。因此,编写这样的代码可以减少主类中的混乱和混乱。或者,对于这些文件,有这样的东西总是更好的吗

from helper_functions import calculate, check_variables, get_stats


class TimeToDrive:

    def __init__(self, avg_traffic_flow, length, speed, number_of_runs):
        self.avg_traffic_flow = avg_traffic_flow
        self.length = length
        self.speed = speed
        self.number_of_runs = number_of_runs

        check_variables(self)
        self.runs = calculate(self)
        self.avg_time, self.avg_speed = get_stats(self)
从随机导入随机、统一
作为pd进口熊猫
def check_变量(时间驱动):
如果timetodrive.speed<25或timetodrive.speed>80:
raise异常(f“不符合{timetodrive.speed}mph的平均速度限制”)
如果timetodrive.avg_交通流量>1或timetodrive.avg_交通流量<0:
引发异常(f“平均流量必须介于0和1之间(1是最佳流量,0是最差流量)”)
如果timetodrive.length<0:
raise异常(f“路由长度不能小于零”)
def计算(驱动时间):
runs=pd.DataFrame(列=[“所需时间”,“平均速度])
对于范围内的(时间驱动。运行次数):
c=行车时间。平均交通流量
x=随机()
指数=4
交通流量=c*x**(1/指数)+(1-c)*x**指数#用于计算交通流量的函数
速度=圆形(行驶时间.速度*交通流量,2)
所需时间小时=整(行驶时间、长度/速度,2)
runs=runs.append({'time required':time\u required\u hours,'average speed':speed},ignore\u index=True)
回程
def get_统计数据(驱动时间):
avg_time=timetodrive.runs['time needed'].mean()
平均速度=行驶时间[“平均速度”]。平均值()
返回平均时间,平均速度
是否有一个地方可以让社区指南展示这方面的最佳实践?
欢迎任何想法或意见

不,有一个作为实例方法并修改实例属性的常规函数不是python式的

为了将类的某些方法的实现推迟到不同的文件中,我建议将主类设为,并将构造函数所需的帮助器方法声明为抽象方法,以便可以在单独的文件中的子类中实现这些帮助器方法

例如:

驾驶时间\u base.py

from abc import ABC, abstractmethod

class TimeToDriveBase(ABC):
    def __init__(self, length, speed):
        self.length = length
        self.speed = speed
        self.avg_time = None
        self.check_variables()
        self.calculate()

    @abstractmethod
    def check_variables(self):
        pass

    @abstractmethod
    def calculate(self):
        pass
from time_to_drive_base import TimeToDriveBase

class TimeToDrive(TimeToDriveBase):
    def check_variables(self):
        assert self.length >= 0
        assert self.speed > 0

    def calculate(self):
        self.avg_time = self.length / self.speed
驾驶时间.py

from abc import ABC, abstractmethod

class TimeToDriveBase(ABC):
    def __init__(self, length, speed):
        self.length = length
        self.speed = speed
        self.avg_time = None
        self.check_variables()
        self.calculate()

    @abstractmethod
    def check_variables(self):
        pass

    @abstractmethod
    def calculate(self):
        pass
from time_to_drive_base import TimeToDriveBase

class TimeToDrive(TimeToDriveBase):
    def check_variables(self):
        assert self.length >= 0
        assert self.speed > 0

    def calculate(self):
        self.avg_time = self.length / self.speed
我正在从事一个大型项目,我们正在导入许多函数作为实例方法,我想知道这是否是一个好的实践

对于大型或小型项目(尽管大型项目从小型开始),您必须很好地组织代码

  • 设计模式是解决这些问题的关键。 -创造/行为/结构模式
好处

  • 可重用性
  • 可读性
  • 蟒蛇和更多
另一种方法-您可以将helper函数分组到一个或多个Util类中

举个简单的例子

class MyMainClass:
    def __init__():
        self.utils = Utils()


class Utils:
    
    @staticmethod
    def my_helper():
         pass

    @staticmethod
    def my_another_helper():
         pass

对我来说,这只会降低整个代码的清晰度。但这似乎基本上是基于em的观点。通常,将文件分离到一个模块中意味着允许从多个位置重用该模块。但是特定于特定类的方法在其他类中通常不会有用。似乎没有合理的理由将它们分开。问这样的代码组织问题可能更好。@juanpa.arrivillaga是的,我完全同意这种问题本质上是基于观点的。但是,我想知道像这样的事情是否可以do@Barmar谢谢你的建议,我将继续在一个
Utils
类上问同样的问题,这个类有一堆静态方法,不应该是一个类,而只是一个常规模块。这就是我提到静态/cls方法的原因。同样,这取决于项目的性质和很多事情。这只是一个想法,以避免许多功能的方式被提到的问题。你看,我有一种感觉,这就是我们所缺少的。我们没有使用子类,我相信我们的很多代码使用它们会变得更有条理