abc don't play well with private method

M

mouadino

i have a problem here :

i want to make a plugin architecture using abstract base class , this
is my base class :

# -*- coding: utf-8 -*-

import abc


class BASE_Connector:
"""
Mount point for plugins which refer to actions that can be
performed.

Plugins implementing this reference should provide the following
methods:

======== ========================================================
connect the connection method that will initialize a transport
layer

__login the login method to use to login in to the server
this one should be called from connect directly

get this method is use for getting the files from the
remote server

close this method is called for closing the connection
suddenly

quit this method is more polite to close the connection
======== ========================================================

"""
__metaclass__ = abc.ABCMeta


@abc.abstractmethod
def connect(self, host, user="", passwd="", port="",
private_key_file="", timeout=100):
""" connect to a remote server this function call the __login
function after the connection is established


-- host : remote server name
-- user : the user name in the remote server
Default : empty string for server that don't need
authentication or use private key instead
-- passwd : password of the user given
Default : empty string for server that don't need
authentication or use private key instead
-- port : the connection port
Default : it's known from the protocol
-- private_key_file : the file containing the private
key used special for ssh connection
Default : empty string
-- timeout : the timeout of the connection
Default : empty string

"""
pass

@abc.abstractmethod
def __login(self):
""" private method to login to the remote server .
it use the user name and the password or the private key
for that

"""

@abc.abstractmethod
def get(self, remote_file_path, local_path="/tmp/
housead_matcher"):
""" method to download the file from the remote server

-- remote_file_path : the path of the file in the remote
server
-- local_path : the local path where the file will be
save
"""
pass

@abc.abstractmethod
def close(self):
""" Close the connection unilaterally(from this host)
"""

@abc.abstractmethod
def quit(self):
""" close the connection. This is the “polite” way to close a
connection
"""


and i define my plugins in a differents module like this :

class FTP_Connector(FTP, Base_Connector) :
""" this class is for the connection to a ftp server

"""


def __init__(self):

FTP.__init__()

def connect(self, host, port, user, passwd, timeout=""):

self.connect(host, port, timeout)
self.___login(user, passwd)


def ___login(self, username="", password=""):

self.login(username, password)


def get(self, remote_file_path, local_path):

remote_file_path = os.path.expanduser(remote_file_path)
local_path = os.path.expanduser(local_path)

remote_directory, remote_file_name =
os.path.split(remote_file_path)
local_file = os.path.join(local_path, remote_file_name)

self.cwd(remote_directory)
self.retrlines("RETR " + remote_file_name, lambda s,
w=local_file.write: w(s+"\n"))

def close(self):

self.close()

def quit(self):

self.quit()



and when i test my code i get this error :
Can't instantiate abstract class FTP_Connector with abstract methods
_BASE_Connector__login

i can understand why. but my problem is why why ? i can't put
"private" method in the ABC class ???
 
B

Bruno Desthuilliers

mouadino a écrit :
i have a problem here :

i want to make a plugin architecture using abstract base class , this
is my base class :

# -*- coding: utf-8 -*-

import abc


class BASE_Connector:
"""
Mount point for plugins which refer to actions that can be
performed.

Plugins implementing this reference should provide the following
methods:

connect the connection method that will initialize a transport
layer

__login the login method to use to login in to the server
this one should be called from connect directly

Removing one of the leading underscores would solve your problem.
"""
__metaclass__ = abc.ABCMeta



@abc.abstractmethod
def __login(self):
""" private method to login to the remote server .
it use the user name and the password or the private key
for that

"""

> and when i test my code i get this error :
> Can't instantiate abstract class FTP_Connector with abstract methods
> _BASE_Connector__login
>
> i can understand why. but my problem is why why ? i can't put
> "private" method in the ABC class ???

There's no such thing as a "private" attribute in Python. The
name-mangling mechanism invoked by "__name" is really meant to avoid
accidental redefinition of the attribute in a derived class.

In this case, your attribute is expected to be redefined, so you
definitly don't want any name mangling here.

Also and FWIW, the naming convention for "implementation attributes" is
a single leading underscore.

Also and FWIW:
class FTP_Connector(FTP, Base_Connector) :
""" this class is for the connection to a ftp server

"""
def close(self):

self.close()

def quit(self):

self.quit()

Don't you see kind of a problem here ? Something like, say, an infinite
recursion ?

HTH
 
M

mouadino

Hello
and thanx for your answer it's was very helpful

but just to clear some thinks :
There's no such thing as a "private" attribute in Python. The
name-mangling mechanism invoked by "__name" is really meant to avoid
accidental redefinition of the attribute in a derived class.
In this case, your attribute is expected to be redefined, so you
definitly don't want any name mangling here.

yes , but what i have supposed is that the name mangling will not be
applied when you use abc especially when you decorate the function
with abc.abstractmethod , because it's will(should) be redefined (so
something is wrong with the abc module) .
Also and FWIW, the naming convention for "implementation attributes" is
a single leading underscore

sorry but i don't agree on this. the two underscore (__) are used in
classes level for defining private method in the python way, and the
one underscore (_) is used in the module level :

"""Prepending a single underscore (_) has some support for protecting
module variables and functions (not included with import * from).
Prepending a double underscore (__) to an instance variable or method
effectively serves to make the variable or method private to its class
(using name mangling). """
src:http://google-styleguide.googlecode.com/svn/trunk/pyguide.html
Don't you see kind of a problem here ? Something like, say, an infinite
recursion ?

yep , thanx
 
M

mouadino

Hello
and thanx for your answer it's was very helpful

but just to clear some thinks :
There's no such thing as a "private" attribute in Python. The
name-mangling mechanism invoked by "__name" is really meant to avoid
accidental redefinition of the attribute in a derived class.
In this case, your attribute is expected to be redefined, so you
definitly don't want any name mangling here.

yes , but what i have supposed is that the name mangling will not be
applied when you use abc especially when you decorate the function
with abc.abstractmethod , because it's will(should) be redefined (so
something is wrong with the abc module) .
Also and FWIW, the naming convention for "implementation attributes" is
a single leading underscore

sorry but i don't agree on this. the two underscore (__) are used in
classes level for defining private method in the python way, and the
one underscore (_) is used in the module level :

"""Prepending a single underscore (_) has some support for protecting
module variables and functions (not included with import * from).
Prepending a double underscore (__) to an instance variable or method
effectively serves to make the variable or method private to its class
(using name mangling). """
src:http://google-styleguide.googlecode.com/svn/trunk/pyguide.html
Don't you see kind of a problem here ? Something like, say, an infinite
recursion ?

yep , thanx
 
M

mouadino

Hello
and thanx for your answer it's was very helpful

but just to clear some thinks :
There's no such thing as a "private" attribute in Python. The
name-mangling mechanism invoked by "__name" is really meant to avoid
accidental redefinition of the attribute in a derived class.
In this case, your attribute is expected to be redefined, so you
definitly don't want any name mangling here.

yes , but what i have supposed is that the name mangling will not be
applied when you use abc especially when you decorate the function
with abc.abstractmethod , because it's will(should) be redefined (so
something is wrong with the abc module) .
Also and FWIW, the naming convention for "implementation attributes" is
a single leading underscore

sorry but i don't agree on this. the two underscore (__) are used in
classes level for defining private method in the python way, and the
one underscore (_) is used in the module level :

"""Prepending a single underscore (_) has some support for protecting
module variables and functions (not included with import * from).
Prepending a double underscore (__) to an instance variable or method
effectively serves to make the variable or method private to its class
(using name mangling). """
src:http://google-styleguide.googlecode.com/svn/trunk/pyguide.html
Don't you see kind of a problem here ? Something like, say, an infinite
recursion ?

yep , thanx
 
S

Steven D'Aprano

yes , but what i have supposed is that the name mangling will not be
applied when you use abc especially when you decorate the function with
abc.abstractmethod , because it's will(should) be redefined (so
something is wrong with the abc module) .

No, your expectations are wrong. Name mangling works the same no matter
what class, whether you are using ABCs or not.

sorry but i don't agree on this. the two underscore (__) are used in
classes level for defining private method in the python way, and the one
underscore (_) is used in the module level :

Whether you agree or not, single underscores are commonly used as the
convention for private methods and attributes. See PEP 8, which is
written by Python's creator, Guido van Rossum:

http://www.python.org/dev/peps/pep-0008/



"""Prepending a single underscore (_) has some support for protecting
module variables and functions (not included with import * from).
Prepending a double underscore (__) to an instance variable or method
effectively serves to make the variable or method private to its class
(using name mangling). """
src:http://google-styleguide.googlecode.com/svn/trunk/pyguide.html


If that's what it says, it's wrong, because there's nothing "effective"
about double-underscore privacy. It's a very weak, easily bypassed
(deliberately and accidentally) form of privacy, and it complicates
debugging.

Generally, most people here recommend you ignore leading double-
underscores and just flag your methods as "private by convention" with a
single leading underscore.
 
B

Bruno Desthuilliers

mouadino a écrit :
Hello
and thanx for your answer it's was very helpful

but just to clear some thinks :



yes , but what i have supposed is that the name mangling will not be
applied when you use abc especially when you decorate the function
with abc.abstractmethod , because it's will(should) be redefined (so
something is wrong with the abc module) .

I agree this might be a bit inconsistant - or at least that your
expectations were rather understandable. But well, that's how it is and
you'll have to deal with it for at least a few years.

Now I bet the name_mangling mechanism is applied in such a way that
implementing your expectations would be rather impractical or add way to
much overhead. Specially when almost no one ever seem to find a use for
this "feature". As far as I'm concerned, I think I didn't used it more
half a dozen times, for some very deep implementation detail of some
miniframework, and mostly because I'm a bit on the paranoid side.
sorry but i don't agree on this.

So you disagree with the established convention followed by (wild guess)
about 99.99% of the regulars here and applied in most of the existing
python code base.


the two underscore (__) are used in
classes level for defining private method in the python way,

The __names are used to invoke name mangling on the attribute (whatever
type it is). It doesn't make it "private" - just a bit less subject to
accidental override. And - I have ton insist on this - it applies to
every attribute. FWIW, Python's "methods" are really not what you may
think they are !-)
and the
one underscore (_) is used in the module level :

.... to avoid export such named symbols in the case of a wildcard import
AND if the module didn't defined an __ALL__ attribute.

The _names are used to denote implementation attribute - IOW, don't
touch unless you're ready to pay the price.
"""Prepending a single underscore (_) has some support for protecting
module variables and functions (not included with import * from).
Prepending a double underscore (__) to an instance variable or method
effectively serves to make the variable or method private to its class
(using name mangling). """
src:http://google-styleguide.googlecode.com/svn/trunk/pyguide.html

This is at best badly formulated and really needs a rewrite.
 
M

mouadino

Hello, and thank you for ALL the informations.

i think i was reading the wrong documents :)

For my use of ABC, i wanted to implement a plugin interface with the
ABC, in first i define a Base class (ABC) that other class
inherit(implement)
so that they can be interfaced as plugins.

but i did have some confusing about the privates method .

thank you all again.

Khalil_ibn_Ahmad (http://en.wikipedia.org/wiki/Khalil_ibn_Ahmad)
sayed :
They are 4 kind of man :
the one that know that he don't know, this is a ignorant so teach
him
the one that know that he know, this is a savant so take from him
the knowledge
the one that don't know that he know, this one has forget so remind
him
the one that don't know that he don't know , this is a fool
 

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,756
Messages
2,569,540
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top