【问题标题】:Why is code outside a class definition run when only the class is imported?为什么只导入类时运行类定义之外的代码?
【发布时间】:2022-01-05 02:17:07
【问题描述】:

期望
我想从另一个文件中导入一个 python 类而不导入文件的其余部分。

问题
当我使用from Exercise_7 import Vehicle(Vehicle 是类)导入类,然后运行我的代码时,Exercise_7.py 中类定义之外的行似乎也在运行。

代码

Exercise_7.py:

import numpy as np

class Vehicle:
  def __init__(self, typeOfVehicle, velocity, colour, electric):
    self.typeOfVehicle = str(typeOfVehicle)
    self.velocity = tuple(velocity)
    self.velocity = np.array(self.velocity)
    self.colour = str(colour)
    self.electric = bool(electric)
      
  def updateVelocity(self, velocityTuple):
    self.velocity = np.array(velocityTuple)

  def allAttributes(self):
    attributes = [self.typeOfVehicle, self.velocity, self.colour, self.electric]
    print(attributes)

  def emissions(self, distance):
    #electric vehicles
    if self.electric == True:
      if self.typeOfVehicle == "Car":
        emission = 1*distance
      elif self.typeOfVehicle == "Truck":
        emission = 5*distance

    else:  #vehicle is not electric
      if self.typeOfVehicle == "Car":
        emission = 10*distance
      elif self.typeOfVehicle == "Truck":
        emission = 50*distance
    return emission

#---TEST CODE THAT IS BEING RUN (when I don't want it to)--- 

vehicle1 = Vehicle("Car", (3,5), "red", False)
vehicle1.updateVelocity((2,6))
vehicle1.allAttributes()
print(vehicle1.emissions(100))

Exercise_8.py(运行时运行不需要的代码的文件):

from Exercise_7 import Vehicle
import numpy as np
import random as r

def newVehicles(type, electric1):
    colours = ["red", "blue", "green", "black", "grey"]
    for i in range(0,50):
        velocity = (r.uniform(1,70), r.uniform(1,70))
        newVehicle = Vehicle(type, velocity, colours[r.randint(0,4)], electric1)
        vehicles.append(newVehicle)

def createVehicles():
    newVehicles("Car", True)
    newVehicles("Car", False)
    newVehicles("Truck", True)
    newVehicles("Truck", False)
    return vehicles

def calculateEmissions(vehicles, time):
    electricCarsEmissions = 0
    nonelectricCarsEmissions = 0
    electricTrucksEmissions = 0
    nonelectricTrucksEmissions = 0
    for vehicle in vehicles:
        speed = (vehicle.velocity[0]**2 + vehicle.velocity[1]**2)**1/2
        distanceTravelled = speed*time
        vehicle.distance = distanceTravelled
        emission = vehicle.emissions(distanceTravelled)
        if vehicle.typeOfVehicle == "Car" and vehicle.electric == True:
            electricCarsEmissions += emission
        elif vehicle.typeOfVehicle == "Car" and vehicle.electric == False:
            nonelectricCarsEmissions += emission
        elif vehicle.typeOfVehicle == "Truck" and vehicle.electric == True:
            electricTrucksEmissions += emission
        elif vehicle.typeOfVehicle == "Truck" and vehicle.electric == False:
            nonelectricTrucksEmissions += emission
    return electricCarsEmissions, nonelectricCarsEmissions, electricTrucksEmissions, nonelectricTrucksEmissions
    
    
vehicles = []
listOfVehicles = createVehicles()
print(calculateEmissions(listOfVehicles, 20))

Exercise_8.py 运行时,输出如下:

['Car', array([2, 6]), 'red', False]  #output from Exercise_7.py code
1000 #output from Exercise_7.py code
(1836161.109986278, 16586342.282856379, 7901210.428254995, 74406974.7703749) #desired output

【问题讨论】:

  • 模块是可执行代码;如果没有完全运行,它们就没有明确定义的内容。 from Exercise_7 import Vehicle 加载整个模块 Exercise_7 到解释器,但只将名称 Vehicle 导入到文件中。
  • "我想从另一个文件中导入一个 python 类而不导入文件的其余部分。"你不能这样做。导入时,模块总是完全加载。

标签: python file class import definition


【解决方案1】:

模块是可执行代码块,defclass 语句也是如此。它们仅在其代码的整个上下文中被明确定义。因此,不可能只加载模块的一部分。

运行from Exercise_7 import Vehicle 仍然需要加载并执行整个模块Exercise_7 到解释器中,即使它只是导入和绑定名称Vehicle 到文件。


不应该在常规导入期间运行的代码应该放在 __main__ guard 中:

if __name__ == "__main__":
    vehicle1 = Vehicle("Car", (3,5), "red", False)
    vehicle1.updateVelocity((2,6))
    vehicle1.allAttributes()
    print(vehicle1.emissions(100))

简单地说,一个模块只有在直接执行时才是__main__ - 例如。与 python -m Exercise_7 一样——但在被另一个模块导入时不会。

【讨论】:

    【解决方案2】:

    这就是解释语言的工作方式(如 python、javascript ...)任何存在于函数或类定义之外的代码都将由解释器(在您的情况下为 python 解释器)执行

    【讨论】:

      猜你喜欢
      • 2011-12-18
      • 2015-03-05
      • 1970-01-01
      • 2015-05-03
      • 2015-10-16
      • 2019-12-28
      • 1970-01-01
      • 2019-05-08
      • 2017-09-18
      相关资源
      最近更新 更多