how to call class name in python? - python-2.7

self.class.name represents the name of the class, if I do
class myClass(object):
def showname(self):
print 'My name is', self.__class__.__name__
this will give me the name of the class
but
class myClass(object):
def __init__(self):
pass
...
"""now I want to call the class by using self.__class__.__name__ so
I dont have to type the class name in function_B()"""
def someFunctions():
return function_A().function_B(self.__class__.__name__)
then this gave me an error saying the self is not defined? any suggestion will be appreciated!

I guess you forgot to indent, and self as a parameter
class myClass(object):
def __init__(self):
pass
...
"""now I want to call the class by using self.__class__.__name__ so
I dont have to type the class name in function_B()"""
def someFunctions(self):
return function_A().function_B(self.__class__.__name__)
Now you can test
x=myClass()
x.someFunctions()
and self is sent to someFunctions

Related

abstractproperty + classmethod decorators in python

I want to enforce childrens to use a classmethod in python2.7.
I tried this:
import abc
class Base(object):
__metaclass__ = abc.ABCMeta
#abc.abstractproperty
def value(self):
pass
#abc.abstractproperty
#classmethod
def text(cls):
pass
class Imp(Base):
TEXT = "hi im text"
#classmethod
def haba(cls):
print 'HI'
#property
def value(self):
return 'asdasd'
#classmethod
#property
def text(cls):
return 'ho ho p'
print Imp.text
print Imp.TEXT
But I'm getting this output:
<bound method ABCMeta.? of <class 'main.Imp'>>
hi im text
How I can properly enforce childrens to implement classmethod properties?
You can see that Imp.TEXT is working but there is no way to enforce creating this member from base class this way
After re-reading your question a few times I concluded that you want the cl method to behave as if it is a property for the class.
First, Python's implementation of abstract method/property checking is meant to be performed at instantiation time only, not at class declaration. I hope you are aware of that.
Second, Python's descriptor protocol allows for the creation of the equivalent of "class properties", although there is no higher level support for that on the language itself - you can create a class which __get__ method returns your calculated property when the instance argument is None (usually descriptors will return 'self' so that they can be retrieved from the class).
Finally - it is possible that by declaring a custom metaclass being abstract itself, and then declaring it as your class metaclass, abstractproperties will trigger in runtime - let's try that - :
In [1]: import abc
In [2]: class AbsPropertyMeta(abc.ABC, type):
...: #abc.abstractproperty
...: def cl(cls):
...: return "Ho ho ho"
...:
In [3]: class ConcreteExample(metaclass=AbsPropertyMeta):
...: pass
...:
(Note that I will develop the answer using Python 3, which should be what you should be using in any new project or for learning purposes as well)
So, as for the former example, the property in the metaclass does work as a "class property", but Python does not enforce its redefinition in the class body.
So, if you really need this design, you should create a complete custom metaclass for that, and let go of the abc.ABCMeta mechanisms at all:
from functools import partial
def abstractclassproperty(func):
func._abstract_property = True
return func
class clsproperty(object):
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
return self.func(owner)
class ABCAbstractClsProperty(type):
def __new__(mcls, name, bases, namespace, **kw):
new_cls = super(ABCAbstractClsProperty, mcls).__new__(mcls, name, bases, namespace, **kw)
for attr_name in dir(new_cls): # Dir retrieves attributes from all superclasses
attr = getattr(new_cls, attr_name)
if getattr(attr, "im_func", None): # Python 2 specific normalization.
attr = attr.im_func
if getattr(attr, '_abstract_property', False) and new_cls.__dict__.get(attr_name) is not attr:
raise TypeError("Can't create class {!r}: abstract property {!r} not implemented".format(name, attr_name))
return new_cls
""" # Python 3:
class A(metaclass=ABCAbstractClsProperty):
#abstractclassproperty
def cl(cls):
pass
"""
class A(object):
__metaclass__ = ABCAbstractClsProperty
#abstractclassproperty
def cl(cls):
pass
try:
class B(A):
pass
except TypeError:
print("Check ok")
class C(A):
#clsproperty
def cl(cls):
return "ho ho ho " + cls.__name__
print(C.cl)

NameError: global name 'MyClass' is not defined in Pepper/Nao

Update: to work around the combination of Choregraphe and Python, I rejected the idea of having #classmethod. Instead I raise AlMemory events in MyCustomClass when I want to make use of MyClass.
I read many posts on NameError but still couldn't find a solution to my problem.
I write a program with Choregraphe using the Python box for Nao.
I got the followings:
class MyClass(GeneratedClass): #GeneratedClass is given
def __init__(self):
GeneratedClass.__init__(self)
#classmethod
def doSomething(cls, a):
print a
class myCustomClass():
def func(self):
MyClass.doSomething(a)
When calling func() from myCustomClass, I got NameError on MyClass.
[ERROR] behavior.box :FMBox::createPythonModule:0 _Behavior__lastUploadedChoregrapheBehaviorbehavior_1275012824__root__test_1: User class evaluation failed with the error:
global name 'MyClass' is not defined
How can I fix that?
As a start your #method and class structure is wrong.
When I ran your code it says this :
class MyClass(GeneratedClass):
#classmethod
def do(self, a):
return a
class myCustomClass():
def func(self):
MyClass.do(a)
Output:
Traceback (most recent call last):
File "test.py", line 236, in <module>
class MyClass(GeneratedClass):
NameError: name 'GeneratedClass' is not defined
Your class structure is completely wrong. If you want to pass a parameter, use __init__ method.
class MyClass:
def __init__(self, GeneratedClass):
self.generated_class = GeneratedClass
def do(self):
doSomething(self.generated_class)
class MyCustomClass:
def func(self):
GeneratedClass = 1
MyClass(GeneratedClass).do()
myCustomClass().func()
If you are using #methodclass you should not pass self, it is cls. Like in this example:
from datetime import date
# random Person
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
#classmethod
def fromBirthYear(cls, name, birthYear):
return cls(name, date.today().year - birthYear)
def display(self):
print(self.name + "'s age is: " + str(self.age))
person = Person('Adam', 19)
person.display()
person1 = Person.fromBirthYear('John', 1985)
person1.display()
In case if you are trying inheritance take this is an example how it should be.
class Mapping:
def __init__(self, iterable):
self.items_list = []
self.__update(iterable)
def update(self, iterable):
for item in iterable:
self.items_list.append(item)
__update = update # private copy of original update() method
class MappingSubclass(Mapping):
def update(self, keys, values):
# provides new signature for update()
# but does not break __init__()
for item in zip(keys, values):
self.items_list.append(item)
Now all in one according to yours:
class GeneratedClass:
def __init__(self):
self.myclass = self
def print(self):
print('hello_people')
class MyClass(GeneratedClass):
def __init__(self,a):
self.a = a
GeneratedClass.__init__(self)
print(a)
#classmethod
def give_param(cls, a):
return cls(a)
class myCustomClass:
def func(self):
MyClass.give_param('aa')
myCustomClass().func()
NOTE: I have used python 3.x.
I think "MyClass" is replaced on the fly by the Choregraphe/PythonBridge interpreter invoked when you press run.
As you can see each choregraphe box classes are named "MyClass", they are so replaced and changed by a generated name like root/class/boxname...
You could try calling and printing the self.getName() in MyClass, to have a clue.
So in your case, you could:
add doSomething directly in myClass
create a not postprocessed, eg:
as:
class MyVeryOneClass:
def __init__(self):
...

Wrap all class methods using a meta class

I'm trying to wrap all of the methods inside a class I wrote with a specific wrapper method.
My class inherits from the python dict class, and I want to wrap all of the methods of this parent class, such as __setitem__, __getitem__, etc.
In my attempts to achieve that I have written a meta class that wraps all the methods inside it's child class, using the __init__ method in the meta class, so I can access the child class's object (and not it's class definition which does not include the parent methods).
However, after running the code, I see the wrapper method is never called. Meaning the wrapping didn't succeed.
Can you help with figuring out what went wrong?
My code:
def wrapper(func):
def wrapped(self, *args, **kwargs):
print 'wrapper.__call__()'
res = func(self, *args, **kwargs)
return res
return wrapped
class MyMeta(type):
def __init__(cls, classname, bases, class_dict):
print 'meta.__init__()'
new_class_dict = {}
for attr_name in dir(cls):
attr = getattr(cls, attr_name)
if hasattr(attr, '__call__'):
attr = wrapper(attr)
new_class_dict[attr_name] = attr
return super(MyMeta, cls).__init__(classname, bases, new_class_dict)
class MyDict(dict):
__metaclass__ = MyMeta
def __init__(self, *args):
print 'child.__init__()'
super(MyDict, self).__init__(*args)
d = MyDict({'key': 'value'})
d['new_key'] = 'new_value'
The printout I get is:
meta.__init__()
child.__init__()
without any reference to the wrapper.__call__() print I placed inside the wrapped method...
When the metaclass __init__ gets called, the class object has already been built so modifying the attributes dict (class_dict in your code) at this stage is totally useless indeed. You want to use setattr instead:
class MyMeta(type):
def __init__(cls, classname, bases, class_dict):
for attr_name in dir(cls):
if attr_name == "__class__":
# the metaclass is a callable attribute too,
# but we want to leave this one alone
continue
attr = getattr(cls, attr_name)
if hasattr(attr, '__call__'):
attr = wrapper(attr)
setattr(cls, attr_name, attr)
# not need for the `return` here
super(MyMeta, cls).__init__(classname, bases, class_dict)

`self.response_class` in `TemplateResponseMixin` don't call super()

Referencece to response_class in Django's code:
django/base.py
class TemplateResponseMixin:
"""A mixin that can be used to render a template."""
response_class = TemplateResponse
def render_to_response(self, context, **response_kwargs):
response_kwargs.setdefault('content_type', self.content_type)
#here
return self.response_class(
#here
request=self.request,
template=self.get_template_names(),
context=context,
using=self.template_engine,
**response_kwargs
)
The class attribute setting response_class = TemplateResponse,
while call it through instance's attribute self.response_class,
I guess it might be super().response_class
How to understand it?
You need to use super() when calling superclass's method. But in case of response_class it's just attribute defined inside TemplateResponseMixin so you can simple accessed it through self.response_class. Since response_class is Class to instancinate you need to add () like this: self.response_class(*args, **kwargs).
You can check this question to get more details about super().
Example:
class A:
def method_a(self):
pass
class B(A):
some_class = SomeClass
def method_a(self):
super().method_a() # This code will find A's method_a and call it
self.some_class() # This will only instancinate some_class attribute of current B's instance

How do I find the class of my static method inside of it?

Given I am inside a #staticmethod, how can I find the name of the current class ?
As i don't have access to self.__class__.__name__
As seen in this answer How to get (sub)class name from a static method in Python?
you can change the #staticmethod to a #classmethod which takes the class as a parameter:
class Bar(object):
#classmethod
def bar(cls):
print cls.__name__
....
If you have control of the method (e.g. it's one you wrote), the best way is to use the #classmethod decorator instead. That will send the class as the first argument:
class Spam(object):
#classmethod
def eggs(cls):
return cls.__name__