对象仅在使用“from”导入时可调用(Python)

时间:2018-01-09 18:43:50

标签: python python-3.x

在线教程之后,我输入了以下代码:

class Car:
    # define and initialize some attributes of Car object
    def __init__(self):
        self.speed = 0
        self.odometer = 0
        self.time = 0

    # 'get' function for current speed
    def say_state(self):
        print("I'm going {} kph!".format(self.speed))

    # 'set' function for current speed
    def accelerate(self):
        self.speed += 5

    # 'set' function for current speed
    def brake(self):
        self.speed -= 5

    # 'set' function for trip time and distance
    def step(self):
        self.odometer += self.speed
        self.time += 1

    # 'get' function for average speed
    def average_speed(self):
        return self.odometer / self.time


if __name__ == "__main__":
    my_car = Car()
    print("I'm a car")
    while True:
        action = input("What should I do? [A]ccelerate, [B]rake, "
                       "show [O]dometer, or show average [S]peed").upper()
        if action not in "ABOS" or len(action) != 1:
            print("I don't know how to do that.")
            continue
        if action == "A":
            my_car.accelerate()
        elif action == "B":
            my_car.brake()
        elif action == "O":
            print("My car has driven {} kilometers".format(my_car.odometer))
        elif action == "S":
            print("My car's average speed was {} kph".format(my_car.average_speed()))

        my_car.step()
        my_car.say_state()

然后,我打破了教程,因为它没有告诉我if __name__ == "main"业务是什么。在其他地方读取,我有点明白,如果模块没有作为主类运行,而是导入,则此语句会阻止执行if语句的代码。所以为了测试这个,我输入了另一个小模块“import_practice.py:< / p>

import Car

corolla = Car()
corolla.say_state()

此代码无法运行,错误“Car is not callable”,所以我认为我的导入错误。我将import Car替换为from Car import Car并且它有效,但根据following answer,它应该没有区别,对吧?事实上,如果答案是正确的,那就不是我想要从我的导入中取出的行为。

3 个答案:

答案 0 :(得分:6)

如果你这样做:

import Car

然后你的代码应该是:

corolla = Car.Car()
corolla.say_state()

当您“导入”模块时,您不会将其所有组件都带到当前命名空间。你只是加载它。如果要引用该模块上的组件,必须通过其模块名称引用它:Car.Car。这里,第一个Car是模块的名称,第二个是类的名称。

如果您确实想要将所有模块的组件导入当前命名空间,则可以执行from Car import *。但我不建议这样做。

之后,你做了from Car import Car。这里,句子表示您将名称CarCar模块带到当前名称空间。因此,您可以在此之后在代码上使用Car

请注意,您所指的答案并不是说import Carfrom Car import Car相同。

答案 1 :(得分:3)

该行

import Car

加载模块 Car,并在中声明所有它声明的内容(即, Car) > namespace Car

该行

from Car import Car

加载模块 Carfrom Car import部分),然后在该模块中声明名称Car class < / em> Car)可在当前命名空间中找到。也就是说,

import Car
Car.Car()

相当于

from Car import Car
Car()

除了全局命名空间中的名称Car引用的内容(整个模块,或者只是一个类)。

请注意,import语句也支持as。有了它,您可以更改当前命名空间中给出的名称:

import Car as CarModule
CarModule.Car()

from Car import Car as CarClass
CarClass()
除了名字之外,

也和其他两个做同样的事情。

答案 2 :(得分:2)

导入麻烦

如果您有一个名为@Singleton的文件并且您致电Car.py,则会将整个模块添加到当前范围。

import Car

这意味着您还可以执行以下操作:

import Car
print(dir(Car))
# [ ... 'Car' ]

另一方面,如果您使用# import the module and alias it import Car as c # add class to local scope as `Car` Car = c.Car 关键字,那么您将在该模块中获得一些内容并将其添加到当前范围:

from

这是from Car import Car corolla = Car.Car() corolla.say_state() 废话是什么?

当您调用文件__name__ == '__main__'时,它会将特殊变量python <my-file-name>设置为字符串__name____main__转换为“如果有人试图将此作为独立脚本运行,则执行以下操作”。另一方面,如果有人在同一个文件上调用if __name__ == '__main__',该区域将触发。