Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #97819 > unrolled thread

variable scope of class objects

Started byJonRob
First post2015-10-19 14:39 -0400
Last post2015-10-20 23:17 +0100
Articles 17 — 9 participants

Back to article view | Back to comp.lang.python


Contents

  variable scope of class objects JonRob - 2015-10-19 14:39 -0400
    Re: variable scope of class objects Random832 <random832@fastmail.com> - 2015-10-19 15:01 -0400
      Re: variable scope of class objects JonRob - 2015-10-20 17:11 -0400
    Re: variable scope of class objects sohcahtoa82@gmail.com - 2015-10-19 16:19 -0700
      Re: variable scope of class objects Terry Reedy <tjreedy@udel.edu> - 2015-10-19 20:03 -0400
    Re: variable scope of class objects Nagy László Zsolt <gandalf@shopzeus.com> - 2015-10-20 07:31 +0200
    Re: variable scope of class objects Luca Menegotto <otlucaDELETE@DELETEyahoo.it> - 2015-10-20 08:17 +0200
      Re: variable scope of class objects Nagy László Zsolt <gandalf@shopzeus.com> - 2015-10-20 08:38 +0200
        Re: variable scope of class objects Luca Menegotto <otlucaDELETE@DELETEyahoo.it> - 2015-10-20 09:23 +0200
      Re: variable scope of class objects JonRob - 2015-10-20 17:33 -0400
        Re: variable scope of class objects Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-10-20 20:18 -0400
          Re: variable scope of class objects JonRob - 2015-10-21 19:35 -0400
            Re: variable scope of class objects Luca Menegotto <otlucaDELETE@DELETEyahoo.it> - 2015-10-22 11:59 +0200
        What does it mean for Python to have “constants”? (was: variable scope of class objects) Ben Finney <ben+python@benfinney.id.au> - 2015-10-21 11:27 +1100
        Re: What does it mean for Python to have “constants”? Nagy László Zsolt <gandalf@shopzeus.com> - 2015-10-21 08:13 +0200
        Re: variable scope of class objects Luca Menegotto <otlucaDELETE@DELETEyahoo.it> - 2015-10-22 07:55 +0200
        Re: variable scope of class objects Erik <python@lucidity.plus.com> - 2015-10-20 23:17 +0100

#97819 — variable scope of class objects

FromJonRob
Date2015-10-19 14:39 -0400
Subjectvariable scope of class objects
Message-ID<q3da2bplpbt2njpoojie8ogfo7te63lhn2@4ax.com>
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
                

[toc] | [next] | [standalone]


#97820

FromRandom832 <random832@fastmail.com>
Date2015-10-19 15:01 -0400
Message-ID<mailman.43.1445281311.878.python-list@python.org>
In reply to#97819
JonRob@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

[toc] | [prev] | [next] | [standalone]


#97844

FromJonRob
Date2015-10-20 17:11 -0400
Message-ID<8abd2btl2mj6n73prpkc4cp016k08fsb23@4ax.com>
In reply to#97820
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, Random832 <random832@fastmail.com>
wrote:

>JonRob@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

[toc] | [prev] | [next] | [standalone]


#97823

Fromsohcahtoa82@gmail.com
Date2015-10-19 16:19 -0700
Message-ID<00fbd018-4188-40da-bacf-394d762c9bed@googlegroups.com>
In reply to#97819
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"

[toc] | [prev] | [next] | [standalone]


#97824

FromTerry Reedy <tjreedy@udel.edu>
Date2015-10-19 20:03 -0400
Message-ID<mailman.45.1445299445.878.python-list@python.org>
In reply to#97823
On 10/19/2015 7:19 PM, sohcahtoa82@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

[toc] | [prev] | [next] | [standalone]


#97825

FromNagy László Zsolt <gandalf@shopzeus.com>
Date2015-10-20 07:31 +0200
Message-ID<mailman.46.1445319071.878.python-list@python.org>
In reply to#97819
>
> #!/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:

[toc] | [prev] | [next] | [standalone]


#97826

FromLuca Menegotto <otlucaDELETE@DELETEyahoo.it>
Date2015-10-20 08:17 +0200
Message-ID<n04m96$tvd$1@speranza.aioe.org>
In reply to#97819
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

[toc] | [prev] | [next] | [standalone]


#97827

FromNagy László Zsolt <gandalf@shopzeus.com>
Date2015-10-20 08:38 +0200
Message-ID<mailman.48.1445323088.878.python-list@python.org>
In reply to#97826
> 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++.



[toc] | [prev] | [next] | [standalone]


#97828

FromLuca Menegotto <otlucaDELETE@DELETEyahoo.it>
Date2015-10-20 09:23 +0200
Message-ID<n04q64$6ls$1@speranza.aioe.org>
In reply to#97827
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

[toc] | [prev] | [next] | [standalone]


#97845

FromJonRob
Date2015-10-20 17:33 -0400
Message-ID<9ocd2btlkq7kp3margtn4sj3mehd7bpimm@4ax.com>
In reply to#97826

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 Menegotto
<otlucaDELETE@DELETEyahoo.it> wrote:

>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).

[toc] | [prev] | [next] | [standalone]


#97849

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2015-10-20 20:18 -0400
Message-ID<mailman.64.1445386763.878.python-list@python.org>
In reply to#97845
On Tue, 20 Oct 2015 17:33:21 -0400, JonRob@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)


			
		
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
    wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#97875

FromJonRob
Date2015-10-21 19:35 -0400
Message-ID<9i7g2b17d3e54cbcf35digbod9216fnovl@4ax.com>
In reply to#97849
@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 Bieber
<wlfraed@ix.netcom.com> wrote:

>On Tue, 20 Oct 2015 17:33:21 -0400, JonRob@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)
>
>
>			
>		

[toc] | [prev] | [next] | [standalone]


#97888

FromLuca Menegotto <otlucaDELETE@DELETEyahoo.it>
Date2015-10-22 11:59 +0200
Message-ID<n0ac2s$ft6$1@speranza.aioe.org>
In reply to#97875
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

[toc] | [prev] | [next] | [standalone]


#97850 — What does it mean for Python to have “constants”? (was: variable scope of class objects)

FromBen Finney <ben+python@benfinney.id.au>
Date2015-10-21 11:27 +1100
SubjectWhat does it mean for Python to have “constants”? (was: variable scope of class objects)
Message-ID<mailman.65.1445387285.878.python-list@python.org>
In reply to#97845
Dennis Lee Bieber <wlfraed@ix.netcom.com> writes:

> (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).

Python now deals with those by making the names keywords::

    >>> True = object()
      File "<stdin>", line 1
    SyntaxError: can't assign to keyword
    >>> False = object()
      File "<stdin>", line 1
    SyntaxError: can't assign to keyword
    >>> None = object()
      File "<stdin>", line 1
    SyntaxError: can't assign to keyword

which seems to rather avoid the question of whether they are “constants”
as would be understood by newcomers experienced with that term in other
languages.

-- 
 \       “Crime is contagious… if the government becomes a lawbreaker, |
  `\          it breeds contempt for the law.” —Justice Louis Brandeis |
_o__)                                                                  |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#97856 — Re: What does it mean for Python to have “constants”?

FromNagy László Zsolt <gandalf@shopzeus.com>
Date2015-10-21 08:13 +0200
SubjectRe: What does it mean for Python to have “constants”?
Message-ID<mailman.69.1445408027.878.python-list@python.org>
In reply to#97845
Dennis Lee Bieber <wlfraed@ix.netcom.com> writes:
>> (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).
> Python now deals with those by making the names keywords::
>
>     >>> True = object()
>       File "<stdin>", line 1
>     SyntaxError: can't assign to keyword
>     >>> False = object()
>       File "<stdin>", line 1
>     SyntaxError: can't assign to keyword
>     >>> None = object()
>       File "<stdin>", line 1
>     SyntaxError: can't assign to keyword
>
> which seems to rather avoid the question of whether they are “constants”
> as would be understood by newcomers experienced with that term in other
> languages.
>
This is true for Python 3, but the OP wrote his program in Python 2. In
Python 2, you can do this (unfortunately):

>>> True, False = False, True
>>> if False:
...     print("DOH!")
...
DOH!

[toc] | [prev] | [next] | [standalone]


#97878

FromLuca Menegotto <otlucaDELETE@DELETEyahoo.it>
Date2015-10-22 07:55 +0200
Message-ID<n09tor$ftt$1@speranza.aioe.org>
In reply to#97845
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

[toc] | [prev] | [next] | [standalone]


#97881

FromErik <python@lucidity.plus.com>
Date2015-10-20 23:17 +0100
Message-ID<mailman.83.1445499854.878.python-list@python.org>
In reply to#97845
On 20/10/15 22:33, JonRob@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.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web