Neither of these implementations has any real benefit.
In test2.py, datetime = datetime is essentially a no-op. It does not change the state of the module. This is completely useless.
test1.py doesn't actually behave particularly differently, either. It just sets datetime as a class attribute, which means that it looks to the class to find datetime instead of the module. This might perform better in some very heavy load circumstances, but not enough that you should be worried about it unless you already know what you're doing.
The fact they invoke self.datetime.time(), though, suggests to me that the author's (assuming you saw someone doing this in their own code) intention was that datetime could be temporarily replaced at runtime, like this:
class FakeDatetime:
def time(self):
return 'from fake datetime'
t = Test1()
t.datetime = FakeDatetime()
print(t.getnow()) # Prints "from fake datetime"
To me, this looks like a misguided attempt to enable using a mock or stub for automated tests. They probably intend for it to be used something like this:
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
The standard solution to mocking in Python is the unittest.mock module (or the mock package if using Python 3.2 or older). This module encourages patching to replace dependencies, rather than something manual like the code you presented:
test3.py
import datetime
class Test3:
def getnow(self):
return datetime.time()
test3tests.py
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