471,090 Members | 1,414 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,090 software developers and data experts.

Instance of class "object"

Howdy,
I wonder why below does not work.

a = object()
a.b = 1 # dynamic bind attribute failed...

To make it correct, we have to create a new class:
class MyClass(object): pass
a = MyClass()
a.b = 1 # OK

Does this strange behavior break the LSP (Liskov substitution principle)?

Regards,
--
ShenLei
Jun 27 '08 #1
14 2351
"甜瓜" <li**************@gmail.comwrites:
Howdy,
I wonder why below does not work.

a = object()
a.b = 1 # dynamic bind attribute failed...

To make it correct, we have to create a new class:
class MyClass(object): pass
a = MyClass()
a.b = 1 # OK
It's annoyingly difficult to search for information on this; "python
class object type inherit bind attribute" aren't sufficiently
distinguishing to know that we're talking about the built-in 'object'
type, and inheriting from it.

I'm interested to know the answer to your question; thanks for asking it.

--
\ "Don't be afraid of missing opportunities. Behind every failure |
`\ is an opportunity somebody wishes they had missed." -- Jane |
_o__) Wagner, via Lily Tomlin |
Ben Finney
Jun 27 '08 #2
"甜瓜" <li**************@gmail.comwrites:
Howdy,
I wonder why below does not work.

a = object()
a.b = 1 # dynamic bind attribute failed...
Because the default object class doesn't have a dict or other
indication of state. It's a "pure" Python object whose only visible
properties are its type and its identity. (On the implementation
level it also has a refcount.)

This is necessary because all other Python objects (both new-style
classes and C extensions) inherit from 'object', on the C level.
Having state in 'object' would mean having that same in *all* other
Python objects. The current design, on the other hand, allows
creation of very lightweight python objects that don't even have a
dict.

Subclassing object instructs Python as to what kind of state you want
your class to have. The default is to have a dict to store
properties:

# a class with dict -- any property goes through dict, and creating a
# Foo object actually creates two objects, one Foo and one dict
class Foo(object):
pass

But you can also specify:

# an efficient 'Pair' class holding two objects
class Pair(object):
__slots__ = 'first', 'second'

Instances of Pair take up even less room that 2-element tuples
because they don't carry the size information in the object.

Now, if the object class carried a dict with it, it would be
impossible to create a class like 'Pair'.
To make it correct, we have to create a new class:
class MyClass(object): pass
a = MyClass()
a.b = 1 # OK

Does this strange behavior break the LSP (Liskov substitution
principle)?
It follows from LSP that what the subclass may not introduce new
preconditions. In this case the subclass accepts a case that the
original class didn't, so it doesn't introduce a new precondition, it
simply weakens (removes) an existing one.
Jun 27 '08 #3
甜瓜 wrote:
I wonder why below does not work.

a = object()
a.b = 1 # dynamic bind attribute failed...
The implementation of slots depends on that behaviour:

http://docs.python.org/ref/slots.html
Does this strange behavior break the LSP (Liskov substitution principle)?
Can you expand on that?

Peter
Jun 27 '08 #4
On May 16, 4:26 am, Peter Otten <__pete...@web.dewrote:
$BE<1;(B wrote:
I wonder why below does not work.
a = object()
a.b = 1 # dynamic bind attribute failed...

The implementation of slots depends on that behaviour:

http://docs.python.org/ref/slots.html
Does this strange behavior break the LSP (Liskov substitution principle)?

Can you expand on that?

Peter
Spirals are important.
Jun 27 '08 #5
On May 16, 8:51 am, castironpi <castiro...@gmail.comwrote:
On May 16, 4:26 am, Peter Otten <__pete...@web.dewrote:
$BE<1;(B wrote:
I wonder why below does not work.
a = object()
a.b = 1 # dynamic bind attribute failed...
The implementation of slots depends on that behaviour:
http://docs.python.org/ref/slots.html
Does this strange behavior break the LSP (Liskov substitution principle)?
Can you expand on that?
Peter

Spirals are important.
I'd be modeling streams, in par. crossing them.
Jun 27 '08 #6
On May 16, 4:16 am, Hrvoje Niksic <hnik...@xemacs.orgwrote:
"$BE<1;(B" <littlesweetme...@gmail.comwrites:
Howdy,
I wonder why below does not work.
a = object()
a.b = 1 # dynamic bind attribute failed...

Because the default object class doesn't have a dict or other
indication of state. It's a "pure" Python object whose only visible
properties are its type and its identity. (On the implementation
level it also has a refcount.)

This is necessary because all other Python objects (both new-style
classes and C extensions) inherit from 'object', on the C level.
Having state in 'object' would mean having that same in *all* other
Python objects. The current design, on the other hand, allows
creation of very lightweight python objects that don't even have a
dict.

Subclassing object instructs Python as to what kind of state you want
your class to have. The default is to have a dict to store
properties:

# a class with dict -- any property goes through dict, and creating a
# Foo object actually creates two objects, one Foo and one dict
class Foo(object):
pass

But you can also specify:

# an efficient 'Pair' class holding two objects
class Pair(object):
__slots__ = 'first', 'second'

Instances of Pair take up even less room that 2-element tuples
because they don't carry the size information in the object.

Now, if the object class carried a dict with it, it would be
impossible to create a class like 'Pair'.
To make it correct, we have to create a new class:
class MyClass(object): pass
a = MyClass()
a.b = 1 # OK
Does this strange behavior break the LSP (Liskov substitution
principle)?

It follows from LSP that what the subclass may not introduce new
preconditions. In this case the subclass accepts a case that the
original class didn't, so it doesn't introduce a new precondition, it
simply weakens (removes) an existing one.
Honor and narrow down:
Having state in 'object' would mean having that same in *all* other
Python objects. The current design, on the other hand, allows
creation of very lightweight python objects that don't even have a
dict.
to:

mass & volume, probably isolating -same-object- and -state-. No
sinking.
Jun 27 '08 #7
On May 16, 8:56 am, castironpi <castiro...@gmail.comwrote:
On May 16, 8:51 am, castironpi <castiro...@gmail.comwrote:


On May 16, 4:26 am, Peter Otten <__pete...@web.dewrote:
$BE<1;(B wrote:
I wonder why below does not work.
a = object()
a.b = 1 # dynamic bind attribute failed...
The implementation of slots depends on that behaviour:
>http://docs.python.org/ref/slots.html
Does this strange behavior break the LSP (Liskov substitution principle)?
Can you expand on that?
Peter
Spirals are important.

I'd be modeling streams, in par. crossing them.- Hide quoted text -

- Show quoted text -
Python 3.0a5 (py3k:62932M, May 9 2008
win32
Type "help", "copyright", "credits" or
>>import parser
import compiler
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named compiler

Does anyone want to model mic-based soundwaves? My recent project has
been color progression over time, and talking about compilers.
Jun 27 '08 #8
On May 16, 9:41 am, castironpi <castiro...@gmail.comwrote:
On May 16, 8:56 am, castironpi <castiro...@gmail.comwrote:


On May 16, 8:51 am, castironpi <castiro...@gmail.comwrote:
On May 16, 4:26 am, Peter Otten <__pete...@web.dewrote:
$BE<1;(B wrote:
I wonder why below does not work.
a = object()
a.b = 1 # dynamic bind attribute failed...
The implementation of slots depends on that behaviour:
http://docs.python.org/ref/slots.html
Does this strange behavior break the LSP (Liskov substitution principle)?
Can you expand on that?
Peter
Spirals are important.
I'd be modeling streams, in par. crossing them.- Hide quoted text -
- Show quoted text -

Python 3.0a5 (py3k:62932M, May 9 2008
win32
Type "help", "copyright", "credits" or>>import parser
>import compiler

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named compiler

Does anyone want to model mic-based soundwaves? My recent project has
been color progression over time, and talking about compilers.- Hide quoted text -

- Show quoted text -
Can 'compiler' come back in? I want to build a compiler + exec.
Jun 27 '08 #9
On May 16, 10:21 am, castironpi <castiro...@gmail.comwrote:
On May 16, 9:41 am, castironpi <castiro...@gmail.comwrote:


On May 16, 8:56 am, castironpi <castiro...@gmail.comwrote:
On May 16, 8:51 am, castironpi <castiro...@gmail.comwrote:
On May 16, 4:26 am, Peter Otten <__pete...@web.dewrote:
$BE<1;(B wrote:
I wonder why below does not work.
a = object()
a.b = 1 # dynamic bind attribute failed...
The implementation of slots depends on that behaviour:
>http://docs.python.org/ref/slots.html
Does this strange behavior break the LSP (Liskov substitution principle)?
Can you expand on that?
Peter
Spirals are important.
I'd be modeling streams, in par. crossing them.- Hide quoted text -
- Show quoted text -
Python 3.0a5 (py3k:62932M, May 9 2008
win32
Type "help", "copyright", "credits" or>>import parser
>>import compiler
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named compiler
Does anyone want to model mic-based soundwaves? My recent project has
been color progression over time, and talking about compilers.- Hide quoted text -
- Show quoted text -

Can 'compiler' come back in? I want to build a compiler + exec.- Hide quoted text -

- Show quoted text -
I am also talking about Mac. I have this one:

def click( self, *_ ):
self.degrees+= 180

Looking entirely unapproachable. Bartender?
Jun 27 '08 #10
On May 16, 4:26 am, Peter Otten <__pete...@web.dewrote:
$BE<1;(B wrote:
I wonder why below does not work.
a = object()
a.b = 1 # dynamic bind attribute failed...

The implementation of slots depends on that behaviour:

http://docs.python.org/ref/slots.html
Does this strange behavior break the LSP (Liskov substitution principle)?

Can you expand on that?

Peter
Yes I can. But what is LSP?
Jun 27 '08 #11
"甜瓜" <li**************@gmail.comwrites:
># an efficient 'Pair' class holding two objects
class Pair(object):
__slots__ = 'first', 'second'

Instances of Pair take up even less room that 2-element tuples
because they don't carry the size information in the object.

Now, if the object class carried a dict with it, it would be
impossible to create a class like 'Pair'.
Really interesting. When the tuple ('first', 'second') is assigning
to __slot__, a special operation is done which makes __slot__
pointing to a magic structure rather than a normal tuple. Am I
right?
It's more like this: when the 'Pair' class is created, the class
creation mechanism notices that the class contain a __slots__ member.
It then uses that member as a specification for the layout of
instances of the 'Pair' type. In this case, instead of a regular dict
(which can hold any number of attributes), Pair instances hold exactly
two attributes, as if[1] it had been declared as:

struct Pair {
PyObject_HEAD // type and refcnt, needed for Python
PyObject *first; // holds pair.first
PyObject *second; // holds pair.second
};

I'm not sure what you mean by "pointing to a magic structure rather
than a normal tuple", but without __slots__, the layout would be
roughly equivalent to:

struct Pair {
PyObject_HEAD // type and refcnt, needed for Python
PyObject *dict; // holds all pair attributes
};
[1]
I'm intentionally simplifying here, for example omitting weakrefs.
Jun 27 '08 #12

"" <li**************@gmail.comwrote in message
news:cd******************************************@ mail.gmail.com...
| # an efficient 'Pair' class holding two objects
| class Pair(object):
| __slots__ = 'first', 'second'
| >
| Instances of Pair take up even less room that 2-element tuples
| because they don't carry the size information in the object.
| >
| Now, if the object class carried a dict with it, it would be
| impossible to create a class like 'Pair'.
| >
| Really interesting. When the tuple ('first', 'second') is assigning to
| __slot__, a special operation is done which makes __slot__ pointing
| to a magic structure rather than a normal tuple. Am I right?

Try it. Run the code and print P.__slots__.
<pause>

Class statements are implemented by calling the metaclass 'type' with 3
args. Type.__new__ uses the information in those args. If the namespace
arg has a __slots__ member, it does something special based on the strings
in the tuple, but it leaves the tuple alone.

Jun 27 '08 #13
On May 16, 4:46 am, "$BE<1;(B" <littlesweetme...@gmail.comwrote:
Howdy,
I wonder why below does not work.

a = object()
a.b = 1 # dynamic bind attribute failed...

To make it correct, we have to create a new class:
class MyClass(object): pass
a = MyClass()
a.b = 1 # OK

Does this strange behavior break the LSP (Liskov substitution principle)?

I suspect it's possible to come up with a property that causes LSP to
be violated for any two given distinct classes.

For example, if the property you're considering is "Raises an
exception when you try to access an attribute", then yes, the subtype
cannot be substituted for the base type and would violate LSP.
However, that's not really such a useful property in most cases.

The reason instances of object don't have dynamic attributes is
because dyanmic attributes are internally represented by a dict
object. To keep memory footprint low, instances of many built-in
types don't have an associated dict and so can't bind attributes
dynamically. Instances of object can't have an associated dict
because, if they did, it would mean all objects would have to have an
associated dict, because all types are subclasses of object.

Because of this, direct instances of object really don't have much use
in Python. It's one main use case is as a sentinel or marker of some
sort. It's only useful property is that it is itself, and nothing
else. But, that property is true of all instances in Python;
therefore any instance may be substituted for an object instances,
therefore it satisfies LSP.

(Phew: what a tangle of nomenclature that was.)
Carl Banks
Jun 27 '08 #14
On May 17, 1:09 am, Carl Banks <pavlovevide...@gmail.comwrote:
On May 16, 4:46 am, "$BE<1;(B" <littlesweetme...@gmail.comwrote:
Howdy,
I wonder why below does not work.
a = object()
a.b = 1 # dynamic bind attribute failed...
To make it correct, we have to create a new class:
class MyClass(object): pass
a = MyClass()
a.b = 1 # OK
Does this strange behavior break the LSP (Liskov substitution principle)?

I suspect it's possible to come up with a property that causes LSP to
be violated for any two given distinct classes.

For example, if the property you're considering is "Raises an
exception when you try to access an attribute", then yes, the subtype
cannot be substituted for the base type and would violate LSP.
However, that's not really such a useful property in most cases.

The reason instances of object don't have dynamic attributes is
because dyanmic attributes are internally represented by a dict
object. To keep memory footprint low, instances of many built-in
types don't have an associated dict and so can't bind attributes
dynamically. Instances of object can't have an associated dict
because, if they did, it would mean all objects would have to have an
associated dict, because all types are subclasses of object.

Because of this, direct instances of object really don't have much use
in Python. It's one main use case is as a sentinel or marker of some
sort. It's only useful property is that it is itself, and nothing
else. But, that property is true of all instances in Python;
therefore any instance may be substituted for an object instances,
therefore it satisfies LSP.

(Phew: what a tangle of nomenclature that was.)

Carl Banks
Python is the same language on sufficiently many distinct machines
that all the people can use it if they want. That means identical
outputs. Do their 100%-ers go with the times?
Jun 27 '08 #15

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

24 posts views Thread by Hung Jung Lu | last post: by
reply views Thread by Bill | last post: by
3 posts views Thread by muesliflakes | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.