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 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
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) ...
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
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.
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
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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,
|
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...
|
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...
|
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...
|
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
| |
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
|
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
|
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)
|
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:
|
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...
|
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...
| |
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,...
|
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...
|
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...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
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
| |
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...
| |