factory functions & methods

A

Aaron Brady

Hello,

I am creating a container. I have some types which are built to be
members of the container. The members need to know which container
they are in, as they call methods on it, such as finding other
members. I want help with the syntax to create the members.
Currently, the container has to be a parameter to the instantiation
methods. I want the option to create members with attribute syntax
instead.

Currently, I have:

cA= Container( )
obA= SomeType( cA )
obB= OtherType( cA, otherarg )

I want:

cA= Container( )
obA= cA.SomeType( )
obB= cA.OtherType( otherarg )

What are my options?

P.S. The container and members are C extension types, not pure Python.
 
A

Aaron Brady

maybe there'sa simpler way, but i think this is what you want, if the
container is the first arg to the other constructors:


...  print x
...>>> from types import MethodType

...   def __init__(self):
...     self.foo = MethodType(foo, self)
...>>> b = Bar()

<__main__.Bar instance at 0x7f35edb091b8>

above is with 3.0.  for some odd reason i thing the order of teh args to
MethodType may have changed recently, so be careful.

andrew

I was thinking that it was a job for '__get__'. (3.0.1.)
.... def __get__( self, instance, owner ):
.... print( self, instance, owner )
........ pass
........ memB= BB
....<class '__main__.BB'> <__main__.C object at 0x00BA2290> <class
'__main__.C'>

So, from above:

cA= Container( )
obA= cA.SomeType( )
obB= cA.OtherType( otherarg )

I would need 'Sometype' and 'Othertype' to be instances of a metatype,
which is the part that concerns me. If it worked, 'Container' could
look like this:

class Container:
SomeType= BoundFirst( SomeType )
OtherType= BoundFirst( OtherType )

It looks like it has a prayer. But how hard will it be in C?
 
G

Gabriel Genellina

Hello,

I am creating a container. I have some types which are built to be
members of the container. The members need to know which container
they are in, as they call methods on it, such as finding other
members. I want help with the syntax to create the members.
Currently, the container has to be a parameter to the instantiation
methods. I want the option to create members with attribute syntax
instead.

Currently, I have:

cA= Container( )
obA= SomeType( cA )
obB= OtherType( cA, otherarg )

I want:

cA= Container( )
obA= cA.SomeType( )
obB= cA.OtherType( otherarg )

What are my options?

What about this? Doesn't require any kind of registration - the Container
just looks for any missing attribute in the global namespace.

py> from functools import partial
py>
py> class Container(object):
.... def __init__(self):
.... self.items = []
.... def add(self, item):
.... self.items.append(item)
.... def __getattr__(self, name):
.... if name in globals():
.... return partial(globals()[name], self)
....
py> class SomeType(object):
.... def __init__(self, parent):
.... self.parent = parent
.... self.parent.add(self)
....
py> class OtherType(SomeType):
.... def __init__(self, parent, arg):
.... SomeType.__init__(self, parent)
.... self.x = arg
....
py> cA = Container()
py> obA = cA.SomeType()
py> obB = cA.OtherType(5)
py> print cA.items
<__main__.OtherType object at said:
P.S. The container and members are C extension types, not pure Python.

It's all implemented in __getattr__, so it should be easy to write the
equivalent C code. (I really don't know if __getattr__ maps to any
predefined slot in the type structure, or what)
 
P

Piet van Oostrum

Aaron Brady said:
AB> Hello,
AB> I am creating a container. I have some types which are built to be
AB> members of the container. The members need to know which container
AB> they are in, as they call methods on it, such as finding other
AB> members. I want help with the syntax to create the members.
AB> Currently, the container has to be a parameter to the instantiation
AB> methods. I want the option to create members with attribute syntax
AB> instead.
AB> Currently, I have:
AB> cA= Container( )
AB> obA= SomeType( cA )
AB> obB= OtherType( cA, otherarg )
AB> I want:
AB> cA= Container( )
AB> obA= cA.SomeType( )
AB> obB= cA.OtherType( otherarg )
AB> What are my options?
AB> P.S. The container and members are C extension types, not pure Python.

You could do something like this (translated to C)

class Container(object):
def __init__(self):
self.items = []
def add(self, item):
self.items.append(item)
def SomeType(self):
newobj = SomeType()
self.add(newobj)
def OtherType(self, arg):
newobj = OtherType(arg)
self.add(newobj)

class SomeType(object):
def __init__(self):
pass

class OtherType(SomeType):
def __init__(self, arg):
SomeType.__init__(self)
self.x = arg

cA = Container()
obA = cA.SomeType()
obB = cA.OtherType(5)
print cA.items
 
A

Aaron Brady

AB> Hello,
AB> I am creating a container.  I have some types which are built to be
AB> members of the container.  The members need to know which container
AB> they are in, as they call methods on it, such as finding other
AB> members.  I want help with the syntax to create the members.
AB> Currently, the container has to be a parameter to the instantiation
AB> methods.  I want the option to create members with attribute syntax
AB> instead.
AB> Currently, I have:
AB> cA= Container( )
AB> obA= SomeType( cA )
AB> obB= OtherType( cA, otherarg )
AB> I want:
AB> cA= Container( )
AB> obA= cA.SomeType( )
AB> obB= cA.OtherType( otherarg )
AB> What are my options?
AB> P.S.  The container and members are C extension types, not pure Python.

You could do something like this (translated to C)

class Container(object):
  def __init__(self):
    self.items = []
  def add(self, item):
    self.items.append(item)
  def SomeType(self):
      newobj = SomeType()
      self.add(newobj)
  def OtherType(self, arg):
      newobj = OtherType(arg)
      self.add(newobj)

class SomeType(object):
  def __init__(self):
      pass

class OtherType(SomeType):
  def __init__(self, arg):
    SomeType.__init__(self)
    self.x = arg

cA = Container()
obA = cA.SomeType()
obB = cA.OtherType(5)
print cA.items

I like it. It's a combination of andrew's suggestion, and what I've
been considering. What I did was (approximately):

class Container:
def __init__( self ):
self.SomeType= type( 'BoundSomeType', (SomeType,),
{ '__new__': custom_new } )
self.OtherType= type( 'BoundOtherType', (OtherType,),
{ '__new__': custom_new } )

cA = Container()
obA = cA.SomeType()
obB = cA.OtherType(5)

It has the advantage that 'cA.SomeType' is a subclass of SomeType;
specifically, that it responds in kind to SomeType. It's a bit
heavyweight on the consumption of resources. 'custom_new' actually
returns an instance of the base.

I am looking for ways to allow user-defined subclasses.

class CustomType( cA.MemberBase ):
...

obC= CustomType( ) #unusable in other instances

-or-

class CustomType( MemberBase ):
...

obC= cA.CustomType( ) #explicit member or dynamic (Gabriel)?
#of base (Piet) or instance (andrew)?

-or-

class CustomType( MemberBase ):
...

obC= CustomType( ) #disallow "as attribute" creation

Or, some combination of -2- and -1- or -3-.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top