Reputation: 265
may I know what is main reason for me to make decision if I should put datetime
as class attribution or not? lets say if I know class Test2
is single class and definitely does not have plan to be inherited by any class
Is it correct to use as class Test2
does where it does not set any import
as class attribute or ?
import datetime
class Test1:
datetime = datetime
def getnow(self):
return self.datetime.time()
import datetime
datetime = datetime
class Test2:
def getnow(self):
return datetime.time()
Upvotes: 0
Views: 189
Reputation: 29884
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
Upvotes: 1
Reputation: 76
Based on the subject did you mean?
this
import datetime
class Test1:
datetime = datetime
def getnow(self):
return self.datetime.time()
vs. this
class Test2:
import datetime
datetime = datetime
def getnow(self):
return self.datetime.time()
It appears your imports should be at the top of your python file. So, in that case, Test1 is the correct way to go.
In Python, what happens when you import inside of a function?
"In general practice, it's probably not that beneficial. In fact, most Python style guides encourage programmers to place all imports at the beginning of the module file."
Upvotes: 0