I have 2 scripts, 1st is All_Methods, and another is All_Testcases, as I am using unittest framework, so here we go.
All_Methods is like:
class All_Services():
def abc(self):
x =1
def bca(self):
print "My Name is Taimoor"
self.abc()
def cba(self):
self.bca()
and on another script which is All_TestCases is like this:
from All_Methods import All_Services as service
class All_TestCases(unittest.TestCase):
def test_1_running_method(self)
service.cba(self)
Exception showing is:
AttributeError: 'All_TestCases' object has no attribute 'bca'
Kindly someone tell me, what I am missing here?
Thanks.
You are not using classes in the usual way when you pass in self to methods that you call on the class. Common is to call the methods on instances of the class and getting the self argument implicitly.
When you call Method.running_query_Athena(self) self is an instance of All_TestCases which does not have the method connecting_Athena.
Did you mean for All_TestCases to derive from All_Methods?
Why is All_Methods a class at all?
Use proper indentation since python is solely based on the basis of how the code is indented.
Please, Please use proper naming conventions; as advised under PEP 8.
You're trying to access an instance method without an instance.
Try the following:
class MyClass:
def my_instance_method(self):
return True
#classmethod
def my_class_method(cls):
return True
#staticmethod
def my_static_method():
return True
This won't work:
>> MyClass.my_instance_method()
TypeError: my_instance_method() missing 1 required positional argument: 'self'
but these will since they are not bound to a class instance being created.
MyClass.my_class_method()
MyClass.my_static_method()
An instance method requires that you instantiate the Class; meaning you use:
MyClass().my_instance_method()
Since you seem to want to set response_id on the class instance; using the self argument which denotes the class instance to get the response_id. - I suggest that you use an instance method and instantiate the class as shown above (note the () after the class name)
Kindly do fix your formatting in the question.
There are quite a few things wrong with the code in the example, but putting that aside.
The error is caused by passing an instance of class A as the self argument to a (non-static) method of class B.
Python will attempt to call this method on the instance of class A, resulting in the missing attribute error.
Here is a simplified example of the problem:
class A:
def is_ham(self):
# Python secretly does `self.is_ham()` here,
# because `self` is the current instance of Class A.
# Unless you explicitly pass `self` when calling the method.
return True
class B:
def is_it_ham(self):
# Note, `self` is an instance of class B here.
return A.is_ham(self)
spam = B()
spam.is_it_ham()
Related
I have an abstract class in python and want to call non-abstract methods in it. Is it possible to do it?
from abc import ABC, abstractmethod
class MyAbstract(ABC):
# Can I call method get_state() from get_current() ?
def get_state():
get_current() # gives me error?
def get_current():
#abstractmethod
def get_time():
I have another python file, Temp.py implement this interface.
In Temp.py, I call the get_state using MyAbstract.get_state(), I get the error stating that get_current() is undefined.
Not sure why.
Any help is appreciated.
In general, all methods have a namespace which is the class or object they're attached to. If you have an instance of a class floating around (e.g. self, most of the time), you can call methods on that instance that automatically pass the instance itself as the first parameter - the instance acts as the namespace for an instance method.
If you're using a class method or a static method, then the namespace is almost always going to be the class they're attached to. If you don't specify a namespace, then python assumes that whatever function you're trying to call is in the global namespace, and if it isn't, then you get a NameError.
In this case, the following should work for you:
class MyAbstract(ABC):
def get_current():
print("current")
def get_state():
MyAbstract.get_current()
#abstractmethod
def get_time():
pass
You can just imagine that you have a little invisible #staticmethod decorator hanging above get_current() that marks it as such. The problem with this is that now you don't get to change the behavior of get_current() in subclasses to affect change in get_state(). The solution to this is to make get_state() a class method:
#classmethod
def get_state(cls):
cls.get_current()
Calling a static method uses identical syntax to calling a class method (in both cases you would do MyAbstract.get_state(), but the latter passes the class you're calling it on as the first argument. You can then use this class as a namespace to find the method get_current() for whatever subclass has most recently defined it, which is how you implement polymorphism with method that would otherwise be static.
Let us consider the following example:
class X:
def run(self):
print("An example.")
X().run()
The output is:
> An example.
But when we omit the reference to the instance:
class X:
def run():
print("An example.")
X().run()
The output is:
TypeError: run() takes 0 positional arguments but 1 was given
When we instantiate the class, __ new __ gets called and the instance is created, ok. But how it requires an instance without defining __ init __? (I'm surprised because, I've always written __ init __ thinking that it was responsible for defining the convention / self name for referencing the variable). I'm confused.
When you call instance.run() if implicitly calls run(instance) which is why you're receiving the error:
TypeError: run() takes 0 positional arguments but 1 was given
That's also the reason why instance methods should have self as the first argument.
Second, you're using the old way of declaring a class - class X:
The new way1 is class X(object): but regardless if you're using the new/old annotation, the call X() will return an instance of the class, even in case you didn't define __init__.
And third, if you want to make it a class method you can either do what Pynchia suggested in the comment above (annotate the method with #staticmethod) or declare the method as a class method by specifying that the first argument is cls and annotating it as a class-method:
class X:
#classmethod
def run(cls):
print "a"
X.run() # prints a
1. According to Mark's comment below, in Python 3 we return to the "old way" of declaring a class. Good to know - thanks Mark!
Recent I study Python,but I have a question about __slots__. In my opinion, it is for limiting parameters in Class, but also limiting the method in Class?
For example:
from types import MethodType
Class Student(object):
__slots__=('name','age')
When I run the code:
def set_age(self,age):
self.age=age
stu=Student()
stu.set_age=MethodType(set_age,stu,Student)
print stu.age
An error has occurred:
stu.set_age=MethodType(set_age,stu,Student)
AttributeError: 'Student' object has no attribute 'set_age'
I want to know, why not use set_age for this class?
Using __slots__ means you don't get a __dict__ with each class instance, and so each instance is more lightweight. The downside is that you cannot modify the methods and cannot add attributes. And you cannot do what you attempted to do, which is to add methods (which would be adding attributes).
Also, the pythonic approach is not to instantiate a MethodType, but to simply create the function in the class namespace. If you're attempting to add or modify the function on the fly, as in monkey-patching, then you simply assign the function to the class, as in:
Student.set_age = set_age
Assigning it to the instance, of course, you can't do if it uses __slots__.
Here's the __slots__ docs:
https://docs.python.org/2/reference/datamodel.html#slots
In new style classes, methods are not instance attributes. Instead, they're class attributes that follow the descriptor protocol by defining a __get__ method. The method call obj.some_method(arg) is equivalent to obj.__class__.method.__get__(obj)(arg), which is in turn, equivalent to obj.__class__.method(obj, arg). The __get__ implementation does the instance binding (sticking obj in as the first argument to method when it is called).
In your example code, you're instead trying to put a hand-bound method as an instance variable of the already-existing instance. This doesn't work because your __slots__ declaration prevents you from adding new instance attributes. However, if you wrote to the class instead, you'd have no problem:
class Foo(object):
__slots__ = () # no instance variables!
def some_method(self, arg):
print(arg)
Foo.some_method = some_method # this works!
f = Foo()
f.some_method() # so does this
This code would also work if you created the instance before adding the method to its class.
Your attribute indeed doesn't have an attribute set_age since you didn't create a slot for it. What did you expect?
Also, it should be __slots__ not __slots (I imagine this is right in your actual code, otherwise you wouldn't be getting the error you're getting).
Why aren't you just using:
class Student(object):
__slots__ = ('name','age')
def set_age(self,age):
self.age = age
where set_age is a method of the Student class rather than adding the function as a method to an instance of the Student class.
Instead of __slots__, I'm using the following method. It allow the use of only a predefined set of parameters:
class A(object):
def __init__(self):
self.__dict__['a']=''
self.__dict__['b']=''
def __getattr__(self,name):
d=getattr(self,'__dict__')
if d.keys().__contains__(name):
return d.__dict__[attr]
else:
raise AttributeError
def __setattr__(self,name,value):
d=getattr(self,'__dict__')
if d.keys().__contains__(name):
d[name] = value
else:
raise AttributeError
The use of getattr(..) is to avoid recursion.
There are some merits usin __slots__ vs __dict__ in term of memory and perhaps speed but this is easy to implement and read.
Maybe the title is a bit misleading, however I wanted to create a simple decorator to decorate some class methods as "allowed" in an RPC mechanism, but I'm stuck on a strange error when trying to access class variables (Python 2.7.5). Check the code below:
class myclass():
rpcallowedmethods = []
def __init__(self):
pass
def rpcenabled(fn):
print fn
print globals()
print myclass
#rpcenabled
def somefunc(self,param):
pass
c = myclass()
Exception: NameError: global name 'myclass' is not defined
Anyone can explain the reason behind this to me?
EDIT:
What I'm asking is more about the fact that python executes the decorator defined in a class and run against decorated classmethods even prior having the class in the globals, so I believed it's more of a logical "bug" in the python implementation than a seemingly obvious NameError
The actual class object is only assigned to its name after its definition is finished. Thus you cannot use the class name during its definition. You can either create a decorator outside of the class to which you explicitly pass the list you want to fill, or use the following:
class myclass():
rpcmethods = []
def _rpcallowed(fct, l=rpcmethods):
l.append(fct)
return fct
#_rpcallowed
def myfct(): pass
Note that the default parameter (l=rpcmethods) is a workaround as you cannot access a class variable inside of a function without a reference to the class or an instance.
The variant with the decorator outside of the class would probably qualify as being "cleaner" than this as it's explicit and reusable, but it would be a bit more code and less specific.
You're abusing decorators. A decorator is meant to add something to thing object is given. "decorating" it somehow.
The more usual way to do something like this would be to decorate both the method and the class. Metaclasses are another way to solve this problem. They're more powerful, but are overkill for your current problem. However, directly decorating the functions might be all you need to do. And save collating the rpc functions for when a proxy is made.
from types import FunctionType
def enable_rpc(func):
func.rpc_enabled = True
return func
def rpc_enabled_class(cls):
functions = [attr for attr in vars(cls).values()
if isinstance(attr, FunctionType)]
cls._rpc_enabled_methods = [
func for func in functions
if getattr(func, "rpc_enabled", False)
]
return cls
#rpc_enabled_class
class SampleClass(object):
#enable_rpc
def my_func(self):
pass
print(SampleClass._rpc_enabled_methods)
Strange error?
print myclass
caused the error. You can't use the name myclass in its definition...
Hello i have this code
class Test(object):
def start_conn(self):
pass
def __init__(self):
self.conn = start_conn()
But this code make this error:
NameError: global name 'start_conn' is not defined
If i write self.conn = self.start_conn() the program works without error, my question is, is a must to call with self the methods of the class when i'm creating a new instance? or is a desgin error from my side?
Thanks a lot
In short, it's a must. You have to refer to the container in which the methods are stored. Most of the time that means referring to self.
The way this works is as follows. When you define a (new-style) class
class FooClass(object):
def my_method(self, arg):
print self.my_method, arg
you create a type object that contains the method in its unbound state. You can then refer to that unbound method via the name of the class (i.e. via FooClass.my_method); but to use the method, you have to explicitly pass a FooClass object via the self parameter (as in FooClass.my_method(fooclass_instance, arg)).
Then, when you instantiate your class (f = FooClass()), the methods of FooClass are bound to the particular instance f. self in each of the methods then refers to that instance (f); this is automatic, so you no longer have to pass f into the method explicitly. But you could still do FooClass.my_method(f, arg); that would be equivalent to f.my_method(arg).
Note, however, that in both cases, self is the container through which the other methods of the class are passed to my_method, which doesn't have access to them through any other avenue.