Re: variable scope of class objects
Il 20/10/2015 23:33, JonRob ha scritto: Hello Luca, I very much appreciated your comments. And I understand the importance of "doing something right" (i.e. convention). This leads me to another question. Because I am interfacing with an I2C sensor I have many register definations to include (30 register addresses and 26 Variables to be red from some of those registers. In your comment you mentioned that convention is to declare variables (and constants?) in the construction (__ini__). I am concerned that the sheer number of varialbe / constants would make it difficult to read. In your opinion, what would be the best method to structure such code? Regards JonRob Let's start from constants. Constants, in Python, simply don't exist (and IMHO this is one of the few lacks of Python). All you can do is to declare a variable and treat it as a constant: you never change it! It doesn't make sense to put a constant declaration at instance level, declaring it in the __init__ part of a class. After all, a constant is an information you want to share. The choice is up to you as the project manager: if you think that your constant is deeply related to the class you're designing, declare it as a class variable; otherwise, declare it at global level (in this case, often I use a separate file dedicated to constant declaration). -- Ciao! Luca -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
On 20/10/15 22:33, jon...@mail.python.org wrote: In your comment you mentioned that convention is to declare variables (and constants?) in the construction (__ini__). I would suggest that 'constants' are not 'declared' in the __init__ method body, but either as class variables or (see later) at module scope. I am concerned that the sheer number of varialbe / constants would make it difficult to read. Remember that "instance variables" in Python are just name bindings to another object which are placed in the object's dictionary. Python is not like some other languages where you declare your object's member variables statically and they all magically exist when you create the object (whether you initialise them or not): none of the bindings exist until an assignment is executed. Therefore, you _must_ have a set of assignments which are executed to create the object with the bindings (or "instance variables") that you require. This is _usually_ done in __init__ with a set of assignments to 'self' - either using default values or values passed in to __init__. You may be getting to the point where the best way to structure this is to write your own module (rather than just a class) which you then import from your main script. For example, you might do something like this: mymodule.py: CONSTANT_X = 0x99 CONSTANT_Y = 0xF00 CONSTANT_Z = "Spam" class MyObject(object): def __init__(self, foo, bar): # 'foo' can be anything. 'bar' must be one of # a specific set of values: if bar not in (CONSTANT_X, CONSTANT_Y): raise ValueError("Parameter 'bar'") self.foo = foo self.bar = bar Then, in your main script you might do something like: import mymodule obj = mymodule.MyObject(100, mymodule.CONSTANT_X) ... then start calling methods on 'obj'. So you just define your address and variable constants at module level and import them along with any class and function definitions. E. -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
Maybe I've been too cryptic. I apologize. Il 22/10/2015 01:35, JonRob ha scritto: @Dennis, Thanks for your example. My structure is very similar. And that's ok. But you can also 'attach' the constants to a class, if it makes sense. For example, the same code of Dennis can be written as: class SensorA(): GYROXREG = 0x0010 GYROYREG = 0x0011 GYROZREG = 0x0001 _registers = [GYROXREG, GYROYREG, GYROZREG] And then you can invoke those constants as: SensorA.GYROXREG to emphasize that they are significant to this class, and to this class only. Luca wrote... Please, note that declaring a variable in the constructor is only a convention: in Python you can add a variable to an object of a class wherever you want in your code (even if it is very dangerous and discouraged). This is the cryptic part. I mean: you can do, and it's perfectly legal: class A(): def __init__(self): self.a = 10 if __name__ == '__main__': o = A() print(o.a) # this is a new member, added on the fly o.b = 20 print(o.b) but, for God's sake, use it only if you have a gun at your head! -- Ciao! Luca -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
@Dennis, Thanks for your example. My structure is very similar. Perhaps I was reading too much into Luca's below statement regarding declaring variables. Regards, JonRob Luca wrote... >Please, note that declaring a variable in the constructor is only a >convention: in Python you can add a variable to an object of a class >wherever you want in your code (even if it is very dangerous and >discouraged). On Tue, 20 Oct 2015 20:18:35 -0400, Dennis Lee Bieberwrote: >On Tue, 20 Oct 2015 17:33:21 -0400, jon...@mail.python.org declaimed the >following: > >> >> >>Hello Luca, >> >>I very much appreciated your comments. And I understand the >>importance of "doing something right" (i.e. convention). >> >>This leads me to another question. >> >>Because I am interfacing with an I2C sensor I have many register >>definations to include (30 register addresses and 26 Variables to be >>red from some of those registers. >>In your comment you mentioned that convention is to declare variables >>(and constants?) in the construction (__ini__). >>I am concerned that the sheer number of varialbe / constants would >>make it difficult to read. >> > > "Constants" are typically defined at module level, using all capitals >as a hint to the reader (Python does not have anything that one might >consider a true constant -- other than the language defined singletons: >None, and maybe by now True and False). > > Register addresses are likely "constants". Not sure about your "26 >Variables"... Do they map directly to registers, or are they extracted as >fields from the values returned -- that is, a register may have two or more >"variables"? Do you read ALL registers on command and hold the values (note >my usage -- values can be held in lists or dictionaries using a single >"variable") for later retrieval by the user, or only read A register on >command by the user and return that value. > >-=-=-=-=- ># registers for a fictitious motion sensor >GYROXREG = 0x0010 >GYROYREG = 0x0011 >GYROZREG = 0x0001 >... >MAGZREG = 0x0100 > >class SensorA(I2C):#I'm assuming class I2C provides read/write functions > _registers = [GYROXREG, GYROYREG, GYROZREG, > ..., MAGZREG] > def __init__(self, SCLpin, SDApin, slaveAddress): > self._SCL = SCLpin > self._SDA = SDApin > self._addr = slaveAddress > self.update() #initial load of values > def update(self): > #basically a loop over all addresses > #I'm not going to try to pseudo code the full I2C protocol > self.values = {}#yes, a dictionary > for reg in _registers: > aValue = self.read(self._SCL, self._SDA, self._addr, > reg) > #inherited from I2C class > self.values[reg] = aValue > > >mySensor = SensorA(21, 22, 0x6) > >while True > mySensor.update() > print ("Gyro X: %s, Y: %s, Z: %s" > % (mySensor.values[GYROXREG], > mySensor.values[GYROYREG], > mySensor.values[GYROZREG])) > time.sleep(1.0) > > > > -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
Il 19/10/2015 20:39, JonRob ha scritto: I (think) I understand that in the below case, the word self could be replaced with "BME280" to explicitly call out a variable. But even still I don't know how explicit call out effects the scope of a variable. These two statements make me think you come from C++ or something similar. In Python you can declare variables at class level, but this declaration must NOT be interpreted in the same manner of a similar declaration in C++: they remain at the abstract level of a class, and they have nothing to do with an instance of a class (in fact, to be correctly invoked, they must be preceeded by the class name). 'self' (or a similar representation, you could use 'this' without problem) gives you access to the instance of the class, even in the constructor; it is important, because the constructor is the place where instance variables should be defined. Something like this: class foo: # invoke with foo._imAtClassLevel _imAtClassLevel = 10 def __init__(self): # need to say how this must be invoked? self._imAtInstanceLevel = 0 no confusion is possible, because: class foo2: _variable = 1000 def __init__(self): # let's initialize an instance variable with # a class variable self._variable = foo2._variable Please, note that declaring a variable in the constructor is only a convention: in Python you can add a variable to an object of a class wherever you want in your code (even if it is very dangerous and discouraged). -- Ciao! Luca -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
Il 20/10/2015 08:38, Nagy László Zsolt ha scritto: When you say "they have nothing to do", it is almost true but not 100%. I know it, but when it comes to eradicate an idea that comes directly from C++-like languages, you must be drastic. Nuances come after... -- Ciao! Luca -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
> These two statements make me think you come from C++ or something > similar. > > In Python you can declare variables at class level, but this > declaration must NOT be interpreted in the same manner of a similar > declaration in C++: they remain at the abstract level of a class, and > they have nothing to do with an instance of a class (in fact, to be > correctly invoked, they must be preceeded by the class name). When you say "they have nothing to do", it is almost true but not 100%. When accessing attributes of an instance, Python first searches in the namespace of the instance. When not found, it searches in the namespace of its class. So for example: >>> >>> class A(object): ... a = ["value 1"] ... def set_a(self): ... # This will bind the value to the name "a" in the namespace of the instance (!!!), not the class ... self.a = ["value 3"] ... >>> a = A() >>> b = A() >>> print A.a # ["value 1"] ['value 1'] >>> print a.a # ["value 1"] ['value 1'] >>> print b.a # ["value 1"] ['value 1'] >>> A.a.append("value 2") >>> print A.a # ["value 1","value 2"] ['value 1', 'value 2'] >>> print a.a # ["value 1","value 2"] ['value 1', 'value 2'] >>> print b.a # ["value 1","value 2"] ['value 1', 'value 2'] >>> a.set_a() >>> print a.a # ["value 3"] ['value 3'] >>> print A.a # ["value 1","value 2"] ['value 1', 'value 2'] >>> print b.a # ["value 1","value 2"] ['value 1', 'value 2'] >>> print A.a is b.a # True True >>> print a.a is b.a # False False >>> b.a.append("value 4") >>> A.a ['value 1', 'value 2', 'value 4'] >>> del a.a >>> a.a ['value 1', 'value 2', 'value 4'] >>> Some objects are designed this way: the attribute with the same name can be bound to an object stored at class level or at instance level, depending on how the object was created or used. In other words: when you access an attrbute through an object, you can very well reach a class attribute instead of an object attribute; and this behaviour can be different for different instances of the same class. Just look at the last attribute deletion - by deleting an attribute of an instance, further attribute access will hit the class level object. The same behaviour is unthinkable with C++. -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
Hello Luca, I very much appreciated your comments. And I understand the importance of "doing something right" (i.e. convention). This leads me to another question. Because I am interfacing with an I2C sensor I have many register definations to include (30 register addresses and 26 Variables to be red from some of those registers. In your comment you mentioned that convention is to declare variables (and constants?) in the construction (__ini__). I am concerned that the sheer number of varialbe / constants would make it difficult to read. In your opinion, what would be the best method to structure such code? Regards JonRob On Tue, 20 Oct 2015 08:17:16 +0200, Luca Menegottowrote: >Il 19/10/2015 20:39, JonRob ha scritto: > >> I (think) I understand that in the below case, the word self could be >> replaced with "BME280" to explicitly call out a variable. >> >> But even still I don't know how explicit call out effects the scope of >> a variable. > >These two statements make me think you come from C++ or something similar. > >In Python you can declare variables at class level, but this declaration >must NOT be interpreted in the same manner of a similar declaration in >C++: they remain at the abstract level of a class, and they have nothing >to do with an instance of a class (in fact, to be correctly invoked, >they must be preceeded by the class name). > >'self' (or a similar representation, you could use 'this' without >problem) gives you access to the instance of the class, even in the >constructor; it is important, because the constructor is the place where >instance variables should be defined. Something like this: > >class foo: > # invoke with foo._imAtClassLevel > _imAtClassLevel = 10 > > def __init__(self): > # need to say how this must be invoked? > self._imAtInstanceLevel = 0 > >no confusion is possible, because: > >class foo2: > _variable = 1000 > > def __init__(self): > # let's initialize an instance variable with > # a class variable > self._variable = foo2._variable > >Please, note that declaring a variable in the constructor is only a >convention: in Python you can add a variable to an object of a class >wherever you want in your code (even if it is very dangerous and >discouraged). -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
Thanks to all who replied to my question. I received a lot of information and points of view that are very helpful. I realize some of you folks spent more that a few minutes. I really appreciate your time. Pardon me that i replied to random832's post and not the original but my original was lost while I was trying to bookmark it. Regards, JonRob On Mon, 19 Oct 2015 15:01:14 -0400, Random832wrote: >jon...@mail.python.org writes: >> >> The below pseudo code is distilled from my 1st attempt at a functional >> Python program on the RasPi. >> >> My questions are: >> What is the scope of class variables? > >You must access them as members of the class or an instance of the class. > >> does the self. prefix modify this scope? > >self just refers to the instance of the class that the function was >called with. It can be any name. > >Python automatically transforms any reference to "[object].func" into a >function (specifically, a bound method object) that will prefix [object] >to the argument list of the defined function. > >> #!/usr/bin/python >> # -- developed using Python 2.7.3 >> >> class BME280: >> >> # all the below are class variables >> # those preceded by an underscore are predefined to some constant > >Constants should be in uppercase, not prefixed with an underscore. > >Names prefixed with an underscore imply that they are "private" (not >really) and therefore other code should not use them directly > >> # those without the underscore are to be "working" variables. > >I don't know what you mean by "working". > >> >> _regT1 = 0x88 >> _regH6 = 0xE7 >> _coeff_P2= 0x82 >> _coeff_P6= 0x32 >> >> filter = 0#should these be "self"? >> t_fine = 0 > >I don't know, should they? If so they need to be in __init__. > >You haven't provided any functions that use them, so it's not clear what >they're for. > >> >> def __init__(self, address=0x76, debug=True): >> self.i2c = Adafruit_I2C(address) >> self.address = address >> self.debug = debug >> >> def pressure_calc(self): >> var1 = self.i2c.readU16(self._regT1,False) >> p = (1048576.0 - var1) * _coeff_P2 >> return p >> >> def read_pressure(self): #called by main application >> pressure_hPa = pressure_calc(self) /10 >> # apply compensation >> return pressure_hPa -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
jon...@mail.python.org writes: > > The below pseudo code is distilled from my 1st attempt at a functional > Python program on the RasPi. > > My questions are: > What is the scope of class variables? You must access them as members of the class or an instance of the class. > does the self. prefix modify this scope? self just refers to the instance of the class that the function was called with. It can be any name. Python automatically transforms any reference to "[object].func" into a function (specifically, a bound method object) that will prefix [object] to the argument list of the defined function. > #!/usr/bin/python > # -- developed using Python 2.7.3 > > class BME280: > > # all the below are class variables > # those preceded by an underscore are predefined to some constant Constants should be in uppercase, not prefixed with an underscore. Names prefixed with an underscore imply that they are "private" (not really) and therefore other code should not use them directly > # those without the underscore are to be "working" variables. I don't know what you mean by "working". > > _regT1 = 0x88 > _regH6 = 0xE7 > _coeff_P2= 0x82 > _coeff_P6= 0x32 > > filter = 0#should these be "self"? > t_fine = 0 I don't know, should they? If so they need to be in __init__. You haven't provided any functions that use them, so it's not clear what they're for. > > def __init__(self, address=0x76, debug=True): > self.i2c = Adafruit_I2C(address) > self.address = address > self.debug = debug > > def pressure_calc(self): > var1 = self.i2c.readU16(self._regT1,False) > p = (1048576.0 - var1) * _coeff_P2 > return p > > def read_pressure(self): #called by main application > pressure_hPa = pressure_calc(self) /10 > # apply compensation > return pressure_hPa -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
On 10/19/2015 7:19 PM, sohcahto...@gmail.com wrote: Class variables are accessible without creating an instance of a class. Also, changing the value of a class variable affects ALL instances of that class. This is because the variable belongs to the class itself, not any of the instances of that class. "self" is used to tell the interpreter that the variable/function you are accessing is a member of an instance of that class. Wrong. The first parameter of a method is an instance of a class. It is conventionally called 'self' but could be any other name. I use 's' for quick private test examples. Here's an example: class MyObject(object): count = 0 def __init__(value): This should be def __init__(self, value): MyObject.count += 1 self.value = value def printStuff(): def print(self): print("My value is ", self.value) > a = MyObject('a') In 2.7.10 TypeError: __init__() takes exactly 1 argument (2 given) Please run code before posting. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
On Monday, October 19, 2015 at 11:39:59 AM UTC-7, JonRob wrote: > Hi, > > I've having trouble understanding the self concept as it applies to > variables. I think I understand how it affects methods. > > I haven't been able to fully grasp the scope of class variables and > the effect of the "self" to the scope of the variable. > > I (think) I understand that in the below case, the word self could be > replaced with "BME280" to explicitly call out a variable. > > But even still I don't know how explicit call out effects the scope of > a variable. > > The below pseudo code is distilled from my 1st attempt at a functional > Python program on the RasPi. > > My questions are: > What is the scope of class variables? > does the self. prefix modify this scope? > > Thanks > > Regards > > JonRob > > > > > #!/usr/bin/python > # -- developed using Python 2.7.3 > > class BME280: > > # all the below are class variables > # those preceded by an underscore are predefined to some constant > # those without the underscore are to be "working" variables. > > _regT1 = 0x88 > _regH6 = 0xE7 > _coeff_P2= 0x82 > _coeff_P6= 0x32 > > filter = 0#should these be "self"? > t_fine = 0 > > def __init__(self, address=0x76, debug=True): > self.i2c = Adafruit_I2C(address) > self.address = address > self.debug = debug > > def pressure_calc(self): > var1 = self.i2c.readU16(self._regT1,False) > p = (1048576.0 - var1) * _coeff_P2 > return p > > def read_pressure(self): #called by main application > pressure_hPa = pressure_calc(self) /10 > # apply compensation > return pressure_hPa Class variables are accessible without creating an instance of a class. Also, changing the value of a class variable affects ALL instances of that class. This is because the variable belongs to the class itself, not any of the instances of that class. "self" is used to tell the interpreter that the variable/function you are accessing is a member of an instance of that class. Here's an example: class MyObject(object): count = 0 def __init__(value): MyObject.count += 1 self.value = value def printStuff(): print("My value is ", self.value) print(MyObject.count) # This will print 0 a = MyObject('a') print(MyObject.count) # This will print 1 print(a.count) # This will also print 1 a.printStuff() # This will print "My value is a" b = MyObject('b') print(a.count) # This will print 2 print(b.count) # This will also print 2 b.printStuff() # This will print "My value is b" -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
> > #!/usr/bin/python > # -- developed using Python 2.7.3 > > class BME280: Not strictly related to the question, but you probably want to use so called "new style classes" when developing a new program for Python version 2. In other words, use: class BME280(object): instead of class BME280: -- https://mail.python.org/mailman/listinfo/python-list
Re: variable scope of class objects
> My questions are: > What is the scope of class variables? In Python, you bind values (objects) to names. It is conceptually different from "setting the value of a variable". In Python, scope applies to names, not variables. When you say "class variable", what do you mean? This may help: A namespace is just a dictionary that binds names to objects. AFAIK there are three kinds of namepaces: local, global and namespaces of other programming tools that can define their own namespaces. Namely: eache modul and class defines its own namespace. So if you bind a name to an object at module level, then that name will be put into the module's namespace. When you bind a name inside a class, for example: class A(object): example_name = 5 then the name "example_name" will be placed in the namespace of the class, and it can be accessed using the class. E.g. "A.example_name". The so called local namespace belongs to functions and methods being called. Any name that is assigned locally inside a method will be a local name of that method, and it will be visible from that method only - except if you explicitely tell that it should be global using the "global" keyword. Formal parameters of methods are also local names, but they get assigned a value when the method is called. The process of assigning actucal objects for formal parameters is called binding. When binding is done, the parameters will become "actual parameters" or "arguments" that have an actual object assigned. Please note the difference between formal parameters and arguments: * Formal parameters are syntactical. They do not have an object (value) assigned. * Arguments are objects bound to formal parameters. They do have an object assigned, but arguments only exist while the method is being called (or ACTIVE, meaning: they are part of the call chain). Methods of objects and classes always have an implicit parameter, that is bound to the object or class the method was called on. In the case of classmethods, it will be a class. In the case of objects, it will be an object. (In case of static methods, there is no implicit parameter.) Apart from being an implicit parameter, there is nothing special about the first parameter of a method. > does the self. prefix modify this scope? It should be clear now, that in this case: def pressure_calc(self): the name "self" is a formal parameter of the "pressure_calc" method, because it is in the formal parameter list. When this method gets called, the name "self" is assigned to the object the method was called on. Because the name "self" is a parameter, it will be a local name of the method, and it will be accessible from inside that method only. -- https://mail.python.org/mailman/listinfo/python-list