Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #97819 > unrolled thread
| Started by | JonRob |
|---|---|
| First post | 2015-10-19 14:39 -0400 |
| Last post | 2015-10-20 23:17 +0100 |
| Articles | 17 — 9 participants |
Back to article view | Back to comp.lang.python
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
| From | JonRob |
|---|---|
| Date | 2015-10-19 14:39 -0400 |
| Subject | variable 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]
| From | Random832 <random832@fastmail.com> |
|---|---|
| Date | 2015-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]
| From | JonRob |
|---|---|
| Date | 2015-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]
| From | sohcahtoa82@gmail.com |
|---|---|
| Date | 2015-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]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2015-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]
| From | Nagy László Zsolt <gandalf@shopzeus.com> |
|---|---|
| Date | 2015-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]
| From | Luca Menegotto <otlucaDELETE@DELETEyahoo.it> |
|---|---|
| Date | 2015-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]
| From | Nagy László Zsolt <gandalf@shopzeus.com> |
|---|---|
| Date | 2015-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]
| From | Luca Menegotto <otlucaDELETE@DELETEyahoo.it> |
|---|---|
| Date | 2015-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]
| From | JonRob |
|---|---|
| Date | 2015-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]
| From | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| Date | 2015-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]
| From | JonRob |
|---|---|
| Date | 2015-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]
| From | Luca Menegotto <otlucaDELETE@DELETEyahoo.it> |
|---|---|
| Date | 2015-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]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2015-10-21 11:27 +1100 |
| Subject | What 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]
| From | Nagy László Zsolt <gandalf@shopzeus.com> |
|---|---|
| Date | 2015-10-21 08:13 +0200 |
| Subject | Re: 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]
| From | Luca Menegotto <otlucaDELETE@DELETEyahoo.it> |
|---|---|
| Date | 2015-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]
| From | Erik <python@lucidity.plus.com> |
|---|---|
| Date | 2015-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