naseeam
asked on
What is being referenced by using dot notation with class name ?
Following are code snippets from python 3.6 standard library logging module, filename __init__.py
On line 1732, class RootLogger gets instantiated. But on line 1733, what is Logger.root ? dot notation is used with object name, not class name ?
On line 1734, what is Logger.manager ? Again, why dot notation is used with class name ?
On line 1732, class RootLogger gets instantiated. But on line 1733, what is Logger.root ? dot notation is used with object name, not class name ?
On line 1734, what is Logger.manager ? Again, why dot notation is used with class name ?
#---------------------------------------------------------------------------
1250 # Logger classes and functions
1251 #---------------------------------------------------------------------------
1252
1253 class Logger(Filterer):
1254 """
1255 Instances of the Logger class represent a single logging channel. A
1256 "logging channel" indicates an area of an application. Exactly how an
1257 "area" is defined is up to the application developer. Since an
1258 application can have any number of areas, logging channels are identified
1259 by a unique string. Application areas can be nested (e.g. an area
1260 of "input processing" might include sub-areas "read CSV files", "read
1261 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
1262 channel names are organized into a namespace hierarchy where levels are
1263 separated by periods, much like the Java or Python package namespace. So
1264 in the instance given above, channel names might be "input" for the upper
1265 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
1266 There is no arbitrary limit to the depth of nesting.
1267 """
1268 def __init__(self, name, level=NOTSET):
1269 """
1270 Initialize the logger with a name and an optional level.
1271 """
1272 Filterer.__init__(self)
1273 self.name = name
1274 self.level = _checkLevel(level)
1275 self.parent = None
1276 self.propagate = True
1277 self.handlers = []
1278 self.disabled = False
1279
1280 def setLevel(self, level):
1281 """
1282 Set the logging level of this logger. level must be an int or a str.
1283 """
1284 self.level = _checkLevel(level)
1285
1286 def debug(self, msg, *args, **kwargs):
class RootLogger(Logger):
1577 """
1578 A root logger is not that different to any other logger, except that
1579 it must have a logging level and there is only one instance of it in
1580 the hierarchy.
1581 """
1582 def __init__(self, level):
1583 """
1584 Initialize the logger with the name "root".
1585 """
1586 Logger.__init__(self, "root", level)
1587
1588 _loggerClass = Logger
root = RootLogger(WARNING)
1733 Logger.root = root
1734 Logger.manager = Manager(Logger.root)
#---------------------------------------------------------------------------
1834 # Utility functions at module level.
1835 # Basically delegate everything to the root logger.
1836 #---------------------------------------------------------------------------
1837
1838 def getLogger(name=None):
1839 """
1840 Return a logger with the specified name, creating it if necessary.
1841
1842 If no name is specified, return the root logger.
1843 """
1844 if name:
1845 return Logger.manager.getLogger(name)
1846 else:
1847 return root
class Manager(object):
1146 """
1147 There is [under normal circumstances] just one Manager instance, which
1148 holds the hierarchy of loggers.
1149 """
1150 def __init__(self, rootnode):
1151 """
1152 Initialize the manager with the root node of the logger hierarchy.
1153 """
1154 self.root = rootnode
1155 self.disable = 0
1156 self.emittedNoHandlerWarning = False
1157 self.loggerDict = {}
1158 self.loggerClass = None
1159 self.logRecordFactory = None
1160
1161 def getLogger(self, name):
1162 """
1163 Get a logger with the specified name (channel name), creating it
1164 if it doesn't yet exist. This name is a dot-separated hierarchical
1165 name, such as "a", "a.b", "a.b.c" or similar.
1166
1167 If a PlaceHolder existed for the specified name [i.e. the logger
1168 didn't exist but a child of it did], replace it with the created
1169 logger and fix up the parent/child references which pointed to the
1170 placeholder to now point to the logger.
1171 """
1172 rv = None
1173 if not isinstance(name, str):
1174 raise TypeError('A logger name must be a string')
1175 _acquireLock()
1176 try:
1177 if name in self.loggerDict:
1178 rv = self.loggerDict[name]
1179 if isinstance(rv, PlaceHolder):
1180 ph = rv
1181 rv = (self.loggerClass or _loggerClass)(name)
1182 rv.manager = self
1183 self.loggerDict[name] = rv
1184 self._fixupChildren(ph, rv)
1185 self._fixupParents(rv)
1186 else:
1187 rv = (self.loggerClass or _loggerClass)(name)
1188 rv.manager = self
1189 self.loggerDict[name] = rv
1190 self._fixupParents(rv)
1191 finally:
1192 _releaseLock()
1193 return rv
ASKER
>> In the RootLogger the "root" variable has class scope because it is referred to with the class name.
Please look at class RootLogger above, there is no "root" variable.
Do you mean in the class Logger "root" variable has class scope? If yes, I don't see "root" variable in class Logger?
Please look at class RootLogger above, there is no "root" variable.
Do you mean in the class Logger "root" variable has class scope? If yes, I don't see "root" variable in class Logger?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you for answering the question and providing a good explanation.
class myClass (object):
root = "something val"
def __init __ (self, value):
self.root = value
mc = myClass ("hello")
print (mc.root)
print (myClass.root)
you will see that the result shows different values. This class has a "root" variable with class scope therefore it is created only once. on the other hand, the "root" variable that is created in the "__init__" method has an instance scope and has nothing to do with the "root" class variable. In the RootLogger the "root" variable has class scope because it is referred to with the class name. I hope you understand me because my English is so so.