Issue in calling the base class methods - python

I am newbie in Python.I know this question is useless.But I am frustrated with my issue.I have 2 methods defined in my base class Animals.When I try to call the base methods in my inherited classes it shows these error:
NameError: name 'display_name' is not defined
class Animals():
def display_name(self):
print ('Name is Mr.X')
def display_age(self):
print('Age is 25')
class Name(Animals):
display_name(self)
class Age(Animals):
display_age(self)
n=Name()
a=Age()
n.display_name()
a.display_age()

You need to refer to the display_name function with a self prefix instead of passing self as an argument.
Also, as noted by Antimony, you need to call the display_name from within a function that is associated with an instance of the class (inside a function that accepts the self argument).
Code that appears outside a method function but inside a class is associated with the whole class, not with any particular instance of that class - using the self variable in this context has no meaning - if you create multiple objects from the class which one does it refer to?
class Animals():
def display_name(self):
print ('Name is Mr.X')
def display_age(self):
print('Age is 25')
class Name(Animals):
def call_display_name(self):
self.display_name()
class Age(Animals):
def call_display_name(self):
self.display_age()
Name().call_display_name()

Related

Passing attribute to parent class via child in decorator

I have this class hierarchy
class ParentMeta(type):
def __new__(v1, name, b, x):
# some code
return super(ParentMeta, v1).__new__(v1, name, b, x)
and then
class ServiceMeta(ParentMeta, AnotherServiceMeta):
pass
The ServiceMeta is normally used as a decorator in add_metaclass i.e.,
#add_metaclass(ServiceMeta)
class MyService(object):
""" Code
The question i want to ask that how can i pass name attribute here? The name attribute is part of ParentMeta.
EDIT:
Link to add_metaclass documentation: https://six.readthedocs.io/#six.add_metaclass
By default, the ServiceMeta is picking up MyService as name for the class. I want to modify this behavior. For that reason i want to pass name value in decorator.

When I use one base class for two different classes, and change a variable within one class instance, the variable in the other class is also changed?

The source code below will raise the exception on the last line. Why the exception is raised if they are two different objects?
class BaseClass(object):
accounts = dict()
def AddAccount(self, account_id, account_var):
if account_id in self.accounts.keys():
raise Exception('Account already exists')
self.accounts.update({account_id: account_var})
class Class1(BaseClass):
pass
class Class2(BaseClass):
pass
ACCOUNT_ID = '123'
c1 = Class1()
c2 = Class2()
c1.AddAccount(ACCOUNT_ID, 'abc')
c2.AddAccount(ACCOUNT_ID, 'abc')
I've tried call the constructor inside each class, but that don't solve the problem. I did like this inside each class:
def __init__(self):
super().__init__()
It looks like the BaseClass is always a static object. When I change in one object, it will change in the other one.
You've defined accounts as a variable of the class, instead of an instance variable. You should instead define accounts in the __init__ method of your base class so that it is instantiated with a different reference for each instance of the class that you create.
class BaseClass(object):
def __init__(self):
self.accounts = dict()
def AddAccount(self, account_id, account_var):
if account_id in self.accounts.keys():
raise Exception('Account already exists')
self.accounts.update({account_id: account_var})
You've defined a class variable in the body of your BaseClass.
Even if you reference it with self.accounts it's not an instance variable.
If you wanted an instance variable, for example, you should initialize it in __init__() with self.accounts = {}

Python 2.7 Ineritance get parent method properties

I am a newbie and have confused learning OOP on python. I am trying to inherit class also using super, but it didn't work as expected.
here my code.
parent.py
class Sale(http.Controller):
def cart(self, **post):
order = request.website.sale_get_order()
....
return request.render("website_sale.cart", values)
child.py
import Sale as sale
class SaleExtend(sale):
def cart(self, **post):
if order:
# do something
....
return super(SaleExtend, self).cart(**post)
I got an error,
AttributeError: 'Sale (extended by SaleExtend)' object has no attribute 'order'
if I just use pass its work correctly, but how to get order value from a parent?
or I did it wrong.
You have no instance nor a class variable order:
class Sale(http.Controller):
def cart(self, **post):
# FUNCTION SCOPE - exists only inside the function
order = request.website.sale_get_order()
....
return request.render("website_sale.cart", values)
Class variables are created like so:
class Ale():
content = "Lager" # this is shared between all instances -> "static"
Instance variables are created like so:
class Ale():
def __init__(self, ale_type):
self.content = ale_type # this is different for each instance unless you
# create multiple instances with the same ale_type
# but they are still "independent" of each other
Function scope variables are creates like so:
class Ale():
# ....
def doSomething(self):
lenContent = len(self.content) # function scope
print( self.content, lenContent )
def doElse(self):
print(lenContent) # NameError - does not exist in scope
See Resolution of names and Short description of the scoping rules?

Multi-Level nested classes with inheritance among inner classes

Let me give a brief explanation of the issue:
I have a server object with several functionalities.
all functionalities have some common code, so this warrants a functionalities base class
Each functionality has its own set of constants, defined in a constants class within the functionality.
The functionality base class has a set of common constants as well.
here is a sample code:
class server:
class base_func:
class common_consts:
name = "name"
def validate(self):
pass
def execute(self):
pass
class func1(base_func):
class consts:
new_name = base_func.common_consts.name #this is where the problem occurs
def get_result(self):
self.validate()
self.execute()
so when i try to use the common_consts from base_func, in func1.consts, I get the following error:
NameError: global name 'base_func' is not defined
I do not know why this happens. Can someone help?
Is there a limitation to the scope of nesting in python, especially 2.7
Also if i remove the top level server class, and have the functionality classes as independent classes, everything seems to work fine. The example of the working code is here:
class base_func:
class common_consts:
name = "name"
def validate(self):
pass
def execute(self):
pass
class func1(base_func):
class consts:
new_name = base_func.common_consts.name #this is where the problem occurs
def get_result(self):
self.validate()
self.execute()
This leads me to believe that there definitely exists some limitation to the nesting depth and namespace scopes in python. I just want to be sure before i make changes to my design.
class server:
class base_func:
class common_consts:
name = "name"
def validate(self):
pass
def execute(self):
pass
# base_func and func1 are at same, level. So, here you can directly use base_func and func1 anywhere
# at top level of the server class
class func1(base_func):
class consts:
new_name = base_func.common_consts.name # this is where the problem occurs
def get_result(self):
self.validate()
self.execute
For a class(classes have their own namespace), variable lookup works like this:
While parsing the class body any variable defined inside the class body can be access directly, but once
it is parsed it becomes a class attribute.
As, the class base_func is inside server class which is still being parsed the func1(base_func) will work fine.
But, for class consts base_func is not at the same level. So, after looking the variable in its body it will directly jump
to its enclosing scope, i.e global namespace in this case.
A fix will be to do the assignement like this:
class server:
class base_func:
class common_consts:
name = "name"
def validate(self):
pass
def execute(self):
pass
class func1(base_func):
class consts:
pass
def get_result(self):
self.validate()
self.execute
func1.consts.new_name = base_func.common_consts.name
You've hit a problem with class scope. The class scope is never made available except to operations that directly occur in the class scope. This is why you can't call method within another method without referencing self.
eg.
class A(object):
def f(self):
pass
def g(self):
f() # error, class scope isn't available
The same is true when you create a nested class. The initial class statement class ClassName(Base): has access to the class scope, but once in the nested class scope you lose access to the enclosing class scope.
Generally, there is no good reason to nest classes in python. You should try to create all classes at module level. You can hide internal classes by either placing them in a sub module or all prefixing them with an underscore.
class _BaseFunctionality(object):
# common constants
name = "name"
value = "value"
def execute(self):
return (self.name, self.value)
class _SpecificFunctionality(_BaseFunctionality):
# specific constants
# override value of value attribute
value = "another_value"
def get_result(self):
assert self.name == "name"
return self.execute()
class Server(object):
functionality = _SpecificFunctionality()
assert _BaseFunctionality.value == "value"
assert _SpecificFunctionality.value == "another_value"
assert Server().functionality.get_result() == ("name", "another_value")

Calling a class method upon creation of Python classes

I'd like to automatically run some code upon class creation that can call other class methods. I have not found a way of doing so from within the class declaration itself and end up creating a #classmethod called __clsinit__ and call it from the defining scope immediately after the class declaration. Is there a method I can define such that it will get automatically called after the class object is created?
You can do this with a metaclass or a class decorator.
A class decorator (since 2.6) is probably easier to understand:
def call_clsinit(cls):
cls._clsinit()
return cls
#call_clsinit
class MyClass:
#classmethod
def _clsinit(cls):
print "MyClass._clsinit()"
Metaclasses are more powerful; they can call code and modify the ingredients of the class before it is created as well as afterwards (also, they can be inherited):
def call_clsinit(*args, **kwargs):
cls = type(*args, **kwargs)
cls._clsinit()
return cls;
class MyClass(object):
__metaclass__ = call_clsinit
#classmethod
def _clsinit(cls):
print "MyClass._clsinit()"

Categories