473,591 Members | 2,797 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

instance + classmethod question


Hello,

Is it possible to tell, which instance was used to call the classmethod
that is currently running?

Background: I have a class called DatabaseConnect ion and it has a
classmethod called process_create_ tables. This method should create some
database tables defined by a database definition object. The
DatabaseConnect ion has many descendants, for example
PostgreSQLConne ction. Descendants know how to create tables in a given
RDBMS type. I also use subclasses of the 'SQLProcessor' class, that
processes SQL commands in different ways (print to stdout, write to
file, execute directly in the database etc.) I would like to use the
process_create_ tables classmethod as is, because sometimes I only need
to save a SQL script. However, I also want to use the same classmethod
to create tables directly into an existing database. That database is
presented as a DatabaseConnect ion instance. In that case, I only want to
create the tables that do not exists yet. Examples:

processor = SQLProcessors.S tdOutProcessor( ) # Print to stdout
PostgreSQLConne ction.process_c reate_tables(pr ocessor,dbdef) # This
sould create all tables, using the processor

processor = SQLProcessors.D irectProcessor( conn) # Execute directly
conn.process_cr eate_tables(pro cessor,dbdef) # This should create
non-existing tables only, using the processor

Is this possible? Maybe there is a better way to achieve this, I'm not
sure. I was thinking about this construct:

@classsmethod
def process_create_ tables(cls,proc essor,dbdef,con n=None)

and then calling it as

conn.process_cr eate_tables(pro cessor,dbdef,co nn)

but this looks very ugly to me. It would be much easier if I could tell
which instance (if any) was used to call the classmethod.

Thanks,

Les

Dec 11 '05 #1
6 1271
Laszlo Zsolt Nagy wrote:

Hello,

Is it possible to tell, which instance was used to call the classmethod
that is currently running?
[snip]
processor = SQLProcessors.S tdOutProcessor( ) # Print to stdout
PostgreSQLConne ction.process_c reate_tables(pr ocessor,dbdef) # This
sould create all tables, using the processor

processor = SQLProcessors.D irectProcessor( conn) # Execute directly
conn.process_cr eate_tables(pro cessor,dbdef) # This should create
non-existing tables only, using the processor

Is this possible?


It looks like you want a method that accepts either a class or an
instance. I would typically create two methods, one for the class-based
table-creating, and one for the instance-based table-creating. However,
if you *have* to do it this way, you can introduce your own descriptor
which should give you the behavior you want::
class ClassOrInstance Method(object): .... def __init__(self, func):
.... self.func = func
.... self.classfunc = classmethod(fun c)
.... def __get__(self, obj, objtype=None):
.... func = obj is None and self.classfunc or self.func
.... return func.__get__(ob j, objtype)
.... class C(object): .... @ClassOrInstanc eMethod
.... def f(*args):
.... print args
.... C.f() (<class '__main__.C'>,) C().f()

(<__main__.C object at 0x00E73D90>,)

Basically, if the descriptor is called from a type (and thus ``obj is
None``), we return a bound classmethod, and if the descriptor is called
from an instance, we return a bound instance method. Of course this now
means you should write your code something like::

@ClassOrInstanc eMethod
def process_create_ tables(cls_or_s elf, processor, dbdef):
...

whose "cls_or_sel f" parameter gives me a bad code smell. YMMV.

STeVe
Dec 11 '05 #2

Hello Steven,

I already implemented this using the form

@classmethod
def methodname(cls, other_params,se lf=None)

but your example code looks so neat! This is exactly what I needed. :-)
In my methods, most code is about string manipulation and calling other
classmethods.
There are only a few places where I can use an instance, but it is not
required.
I would like to reuse as most code as possible, so I do not want to
create two different
methods. That would result in duplicating code. Now the only problem is
how I name this.
It is not a classmethod, but it is also not a normal method. All right,
it is a
"ClassOrInstanc eMethod". Amazing! Probably Python is the only language
that is
flexible enough to do this. :-)

Thanks again!

Laszlo
Steven Bethard wrote:
Laszlo Zsolt Nagy wrote:

Hello,

Is it possible to tell, which instance was used to call the classmethod
that is currently running?

class ClassOrInstance Method(object):

... def __init__(self, func):
... self.func = func
... self.classfunc = classmethod(fun c)
... def __get__(self, obj, objtype=None):
... func = obj is None and self.classfunc or self.func
... return func.__get__(ob j, objtype)
...


Dec 11 '05 #3
Laszlo Zsolt Nagy wrote:
In my methods, most code is about string manipulation and calling other
classmethods.
There are only a few places where I can use an instance, but it is not
required.
I would like to reuse as most code as possible, so I do not want to
create two different
methods. That would result in duplicating code.


I would tend to do this by creating a wrapper method for the instance
that did the appropriate stuff for the instance, and then called the
classmethod, e.g.:

class C(object):
...
@classmethod
def do_stuff(cls, *args):
...
def do_instance_stu ff(self, *args):
# instance stuff
...
self.do_stuff(* args)
# more instance stuff
...

But it does require some factoring of the classmethod so that it makes
sense to call it in this manner.

STeVe
Dec 11 '05 #4
Laszlo Zsolt Nagy <ga*****@design aproduct.biz> writes:
Is it possible to tell, which instance was used to call the
classmethod that is currently running?


Ok, I read through what got to my nntp server, and I'm still
completely confused.

A class method isn't necessarilry called by an instance. That's why
it's a class method. What should happen in that case?

You provided an example where you passed self as an optional
argument. If it's going to have self, shouldn't it be an instance
method?

I think I agree with Steven - you should use two methods. You deal
with the issue of duplicated code by pulling the code that would be
duplicated out into private methods. This would be a straightforward
refactoring problem.

<mike
--
Mike Meyer <mw*@mired.or g> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Dec 11 '05 #5
Mike Meyer wrote:
Laszlo Zsolt Nagy <ga*****@design aproduct.biz> writes:

Is it possible to tell, which instance was used to call the
classmethod that is currently running?
Ok, I read through what got to my nntp server, and I'm still
completely confused.

A class method isn't necessarilry called by an instance. That's why
it's a class method. What should happen in that case?

Here is the answer (an example):

@ClassOrInstanc eMethod
def process_create_ table(cls_or_se lf,tabledef,pro cessor):
"""Process the CREATE TABLE command.

@param tabledef: a L{TableDefiniti on} instance.
@param processor: a L{SQLProcessor} instance."""
hname = cls_or_self.has hident(tabledef .name)
if (isinstance(cls _or_self,type)) or (not
cls_or_self.ist ableexists(hnam e)):
processor.addli ne("create table %s \n ("% hname)
for field in tabledef.fields :
if not (field() is None):

cls_or_self.pro cess_create_tab le_field(field( ),processor)
processor.addli ne(",")
processor.trunc ate_last_comma( )
processor.addli ne("")
processor.addli ne(")")
cls_or_self.add tablespaceclaus e(tabledef,proc essor)
processor.proce ssbuffer()

So if the method was called with an instance, it will check if the table
exists and create the table only if it did not exist before.
But if the method was called with a class, it will create the table anyway.

The above method is just a short example. I have many methods for
creating sequences, triggers, constraings etc.
The full pattern is:

def process_XXXXXXX (cls_or_self,de fobject,process or):
<longer code>
<a condition, depending on the class or the instance>
<longer code>
<another condition, depending on the class or the instance>
<longer code>

There are two reasons why I do not want to create two methods (one
instance and one class method).

1. If you look the above pattern, it is clear that the method does the
same thing, just there are some conditions when I call it with an
instance. I do not want to call "process_create _table_with_cla ss" and
"process_create _table_with_ins tance", because the name of the method
should reflect what it does primarily. (BTW, I also looked at
multimethods, but they are not exactly for this kind of problem.)

2. The pattern above makes it clear that I just can't easily split the
method into elementary parts. Steven wrote this pattern:
class C(object):
...
@classmethod
def do_stuff(cls, *args):
...
def do_instance_stu ff(self, *args):
# instance stuff
...
self.do_stuff(* args)
# more instance stuff

But I cannot do this, because primarily I do class stuff, and in some
cases, I can make use of an instance (but do not require it).
Comments welcome

Les

Dec 12 '05 #6
Laszlo Zsolt Nagy <ga*****@design aproduct.biz> writes:
Mike Meyer wrote:
Laszlo Zsolt Nagy <ga*****@design aproduct.biz> writes:
Is it possible to tell, which instance was used to call the
classmetho d that is currently running?Ok, I read through what got to my nntp server, and I'm still
completely confused.
A class method isn't necessarilry called by an instance. That's why
it's a class method. What should happen in that case?

Here is the answer (an example):

@ClassOrInstanc eMethod
def process_create_ table(cls_or_se lf,tabledef,pro cessor):
"""Process the CREATE TABLE command.

@param tabledef: a L{TableDefiniti on} instance.
@param processor: a L{SQLProcessor} instance."""
hname = cls_or_self.has hident(tabledef .name)
if (isinstance(cls _or_self,type)) or (not
cls_or_self.ist ableexists(hnam e)):
processor.addli ne("create table %s \n ("% hname)
for field in tabledef.fields :
if not (field() is None):
cls_or_self.pro cess_create_tab le_field(field( ),processor)
processor.addli ne(",")
processor.trunc ate_last_comma( )
processor.addli ne("")
processor.addli ne(")")
cls_or_self.add tablespaceclaus e(tabledef,proc essor)
processor.proce ssbuffer()


I assume that hashident, istableexists, process_create_ table_field and
addtablespacecl ause all do this screwy ClassOrInstance Method thing?
There are two reasons why I do not want to create two methods (one
instance and one class method).

1. If you look the above pattern, it is clear that the method does the
same thing, just there are some conditions when I call it with an
instance. I do not want to call "process_create _table_with_cla ss" and
"process_create _table_with_ins tance", because the name of the method
should reflect what it does primarily. (BTW, I also looked at
multimethods, but they are not exactly for this kind of problem.)
Well, I'd call them process_create_ table_for_insta nce and
create_table_fo r_class, but that's just me.
2. The pattern above makes it clear that I just can't easily split the
method into elementary parts. Steven wrote this pattern:
I didn't say it would be easy - just well understood, and on seeing
this, maybe not that. On the other hand, being hard doesn't mean it's
not worth doing.
But I cannot do this, because primarily I do class stuff, and in some
cases, I can make use of an instance (but do not require it).
Comments welcome


Proposing an alternative design is pretty much impossible, because I
don't know how the class hierarchy fits together. If there isn't much
of a hierarchy, maybe you'd be better off with an ADT model than an
object model?

<mike
--
Mike Meyer <mw*@mired.or g> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Dec 13 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

37
17054
by: Grzegorz Staniak | last post by:
Hello, I'm a newbie Python user, a systems administrator - I've been trying to switch from Perl to Python for administrative tasks - and one thing I cannot understand so far is why I need the special 'self' (or anything esle) argument in class method definitions. I might have missed an explanation in the docs, a quick Google search did not help. Is there somewhere on the web you could direct me to? Thanks,
6
1348
by: Zak Arntson | last post by:
I'm currently implementing a game GUI, where there are three components to the screen: A battle, a command button area and a city view area. Each of these are rectangular, and handle interactions in different ways. For example, on the battle "frame" you can select units, right-click to deliver context-sensitive commands, etc. On the command frame, you select buttons to deliver commands, change the state of the battle frame (i.e., a move...
18
6941
by: John M. Gabriele | last post by:
I've done some C++ and Java in the past, and have recently learned a fair amount of Python. One thing I still really don't get though is the difference between class methods and instance methods. I guess I'll try to narrow it down to a few specific questions, but any further input offered on the subject is greatly appreciated: 1. Are all of my class's methods supposed to take 'self' as their first arg? 2. Am I then supposed to call...
2
2280
by: Ksenia Marasanova | last post by:
Hi all, I am creating some library, and want use "declarative" style in the subclasses as much as possible, while the actual use will be more method-like. Just to give an impression, the library would be something like this: class Baseclass(object): # lot's of code goes here...
3
2017
by: Giovanni Bajo | last post by:
Hello, what's the magic needed to reuse the base-class implementation of a classmethod? class A(object): @classmethod def foo(cls, a,b): # do something pass
3
2130
by: andychambers2002 | last post by:
Hi, I'm trying to write a method that needs to know both the class name and the instance details class A: @classmethod def meth(cls, self): print cls
1
4990
by: s.lipnevich | last post by:
Hi All, Is anything wrong with the following code? class Superclass(object): def __new__(cls): # Questioning the statement below return super(Superclass, cls).__new__(Subclass) class Subclass(Superclass): pass
11
1607
by: Paulo da Silva | last post by:
I would like to implement something like this: class C1: def __init__(self,xxx): if ... : self.foo = foo self.bar = bar else: self=C1.load(xxx)
1
156
by: Scott SA | last post by:
On 4/24/08, Bruno Desthuilliers (bruno.42.desthuilliers@websiteburo.invalid) wrote: I'm rapidly becoming a "django junkie"^TM In retrospect, my example was poorer than I first thought - or was it my spec. Regardless, it wasn't quite right. The question/premise should have been:
0
7934
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8362
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
7992
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8225
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6639
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
5732
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
3891
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2378
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
0
1199
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.