I have the following class:
import Radar
class Domain(Radar):
URL = 'https://mxtoolbox.com/DNSLookup.aspx'
ADDRESS_KEYS = ('mailing_address', 'city_name', 'state_name', 'zip_code',
'country_name')
GENERAL_PARAMS = {'format': 'json'}
BALANCE_PARAMS = {**Radar.GENERAL_PARAMS, 'account': 'balance'}
SUCCESSFUL_QUERY = 1
API_KEY_ERROR_REASON = 'Invalid API Key'
MASKED_ENTITY_INDICATOR = 'To View Unmasked Data'
def __init__(self, *args, **kwargs):
self.entity_title = 'Crawling'
super().__init__(*args, **kwargs)
The class' methods (only them) access each of these constant static members few times.
What are the advantages/disadvantages of putting these variables in the outer scope (as a file level variables – and not class level static variables)?
Even though I know both approaches would work, I wonder where is the best place put the variables – inside the class or above it.
The other option:
import Radar
URL = 'https://mxtoolbox.com/DNSLookup.aspx'
ADDRESS_KEYS = ('mailing_address', 'city_name', 'state_name', 'zip_code',
'country_name')
GENERAL_PARAMS = {'format': 'json'}
BALANCE_PARAMS = {**Radar.GENERAL_PARAMS, 'account': 'balance'}
SUCCESSFUL_QUERY = 1
API_KEY_ERROR_REASON = 'Invalid API Key'
MASKED_ENTITY_INDICATOR = 'To View Unmasked Data'
class Domain(Radar):
def __init__(self, *args, **kwargs):
self.entity_title = 'Crawling'
super().__init__(*args, **kwargs)
Best Answer
This is a mostly stylistic choice. In the end, it doesn't matter. There are some finer differences depending on how they are used.
If the constants are only used within the module, using module-level variables is more convenient. (Compare class variables below).
If the constants are used outside of this module, then module-level variables have the advantage that you can
import
them.Class variables have the advantage that they are bundled in that class. This may provide a more convenient interface because you don't have to pass them around individually. For example, the
Enum
class does this nicely. But in reverse: why would you be bundling them unless they are used together?Class variables in Python do have some gotchas.
property
, or more generally: the descriptor protocol).URL
variable in a method, you have to sayDomain.URL
orself.URL
. Module-level variables can be accessed directly.In general, Python doesn't force you to stuff everything into a class. You should use this freedom because most variables or functions don't belong into a class. If in doubt, use free variables/functions instead of fields/methods within a class. You can always change your mind later and refactor.