Python 有没有理由将导入库作为类属性?

Python 有没有理由将导入库作为类属性?,python,class,Python,Class,请问我决定是否将datetime作为班级归属的主要原因是什么?假设我知道类Test2是单个类,并且肯定没有被任何类继承的计划 在未将任何import设置为class属性或属性的情况下,使用as classTest2does是否正确 test1.py test2.py 基于这个主题,你是说 这个 import datetime class Test1: datetime = datetime def getnow(self): return self.dateti

请问我决定是否将
datetime
作为班级归属的主要原因是什么?假设我知道
类Test2
是单个类,并且肯定没有被任何类继承的计划

在未将任何
import
设置为class属性或属性的情况下,使用as class
Test2
does是否正确

test1.py test2.py
基于这个主题,你是说

这个

import datetime

class Test1:
    datetime = datetime
    def getnow(self):
        return self.datetime.time()
class Test2:
import datetime

    datetime = datetime
    def getnow(self):
        return self.datetime.time()
与此相比

import datetime

class Test1:
    datetime = datetime
    def getnow(self):
        return self.datetime.time()
class Test2:
import datetime

    datetime = datetime
    def getnow(self):
        return self.datetime.time()
看起来您的导入应该位于python文件的顶部。因此,在这种情况下,Test1是正确的方法


“在一般实践中,这可能没有什么好处。事实上,大多数Python风格的指南都鼓励程序员将所有导入放在模块文件的开头。”

这两种实现都没有任何真正的好处

在test2.py中,
datetime=datetime
本质上是一个no-op。它不会改变模块的状态。这完全没有用

实际上,test1.py的行为也没有特别不同。它只是将
datetime
设置为类属性,这意味着它将查找类来查找
datetime
,而不是模块。在一些非常重的负载情况下,这可能会表现得更好,但这还不足以让您担心,除非您已经知道自己在做什么

但是,他们调用
self.datetime.time()
的事实向我表明,作者(假设您在自己的代码中看到有人这样做)的意图是可以在运行时临时替换
datetime
,如下所示:

class FakeDatetime:
    def time(self):
        return 'from fake datetime'

t = Test1()
t.datetime = FakeDatetime()
print(t.getnow()) # Prints "from fake datetime"
import unittest
from test1 import Test1

class TestStringMethods(unittest.TestCase):
    def test_my_method():
        mock = MyMock()
        expected_value = 'my value'
        # Set up code to make mock.time() return expected value

        t = Test1()
        t.datetime = mock
        assert t.time() == expected_value
在我看来,这似乎是一种误导性的尝试,试图使用模拟存根进行自动化测试。他们可能打算这样使用它:

class FakeDatetime:
    def time(self):
        return 'from fake datetime'

t = Test1()
t.datetime = FakeDatetime()
print(t.getnow()) # Prints "from fake datetime"
import unittest
from test1 import Test1

class TestStringMethods(unittest.TestCase):
    def test_my_method():
        mock = MyMock()
        expected_value = 'my value'
        # Set up code to make mock.time() return expected value

        t = Test1()
        t.datetime = mock
        assert t.time() == expected_value
Python中模拟的标准解决方案是(或者如果使用Python 3.2或更早版本)。本模块鼓励通过修补替换依赖项,而不是像您提供的代码这样的手动操作:

test3.py

import datetime

class Test3:
    def getnow(self):
        return datetime.time()
import unittest
from unittest import mock
from test3 import Test3

class TestStringMethods(unittest.TestCase):
    @mock.patch('test3.datetime')
    def test_my_method(datetime_mock):
        expected_value = 'my value'
        datetime_mock.time.return_value = expected_value

        t = Test3()
        assert t.time() == expected_value
        # Original datetime is restored by patch automatically when method exits
test3tests.py

import datetime

class Test3:
    def getnow(self):
        return datetime.time()
import unittest
from unittest import mock
from test3 import Test3

class TestStringMethods(unittest.TestCase):
    @mock.patch('test3.datetime')
    def test_my_method(datetime_mock):
        expected_value = 'my value'
        datetime_mock.time.return_value = expected_value

        t = Test3()
        assert t.time() == expected_value
        # Original datetime is restored by patch automatically when method exits

Test2更好,没有必要让类变量成为您将要使用的全局变量。但是在测试2中,请注意,
datetime=datetime
是多余的。为什么您认为这样做是有理由的?简短回答-没有理由我不理解这两个例子。为什么在测试2中
datetime=datetime
。。。不应该有任何理由说明
datetime=datetime
但这两种情况都没有任何作用。没有必要这样做。我没有关注代码在做什么。我只是从语言语法和最佳实践的角度来看它。导入从何处获得?导入位于文件顶部,然后可以执行所有其他的
datetime
重新绑定。如果您希望
getnow
返回当前时间,只需
return datetime.datetime.now()
,但不需要将其作为类属性。因此,您可以使用两行代码来实现这一点

导入datetime
返回self.datetime.time()
导入后返回1,具体取决于您是否需要自己的类。用户定义的类根本不是必需的。但我不知道你为什么要问这个问题;我并不是说你需要改变你的答案,但你自己对此不确定吗?