I'm currently making a simple script that let's me control multiple (32) switches and routers trough a Access server. I already made a class that initiates the serial connection
Anyway, my question is how do I use an inherited method? I have a grandparent Devices that has 2 children(Father) Router and Switches. These 2 children became father to a few children let's keep it simple with SwitchA SwitchB & RouterA. Now in Cisco devices some configurations are 'standard' but not all. Let's say I want to enter "configuration terminal" trough the serial port.
Focus:
class Devices(object):
'Grandparent Class for Cisco Devices'
def __init__(self, a):
self.__a = a
def enterConfT(self):
self.__a.send( "\r" )
self.__a.send("enable\r")
print("enabled")
self.__a.send( "config terminal\r" )
print("Entered global configuration mode.")
class Switches(Devices):
'Switches Parent?'
def __init__(self):
pass
def do_nothing_yet(self):
pass
class switchA(Switches):
'Catalyst 3850 Teletest'
def __init__(self, x):
self.__x = x
In another file I got:
y = TClasses.cisco.test.switchA(serial1)
y.enterConfT()
this gives the following exception/error(I took out file directories):
'switchA' object has no attribute '_Devices__a'
['Traceback (most recent call last):\n', ' File "/sorry_privacy/test.py", line 30, in <module>\n y.enterConfT()\n', ' File "/sorry_hehe/TClasses.py", line 24, in enterConfT\n self.__a.send( "\\r" )\n', "AttributeError: 'switchA' object has no attribute '_Devices__a'\n"]
I want to be able to keep the variables a and x private while they are pointing to the same object.
What I know from OOP and C++, Minimalise repeated code and I didn't seem to have a problem with grandparent inheritence in C++ but I know Python works differently. I also read a few Q&A but couldn't really understand what they meant. I'm a beginner Python scripter.
Thank you in advance and excuse my english.
Found the answer. Using super() in the init I can initialize from parent.
This was helpfull, as I tend to read very fast and globally.
https://www.python-course.eu/python3_inheritance.php
Related
First of all I apologize if I have writen some word incorrectly - English is my second language.
But anyway I've been working on an text RPG for like a week and just started on an combat system and I have all of the player and enemy statistics in clases.
This is just part of my code but it's enough. So I have made a function which levels up my character.
class player:
def __init__(self):
self.name='Hero'
self.lvl=1
self.xp=0
self.lvl_next=25
self.str=1
self.dex=1
self.int=1
def pl_level(self):
Nstr=0
Ndex=0
Nint=0
while player.xp>=player.lvl_next:
player.lvl+=1
player.xp-=player.lvl_next
player.lvl_next=round(player.lvl_next*1.5)
Nstr+=1
Ndex+=1
Nint+=1
print('Level:', player.lvl)
print('STR {} +{} DEX {} +{} INT {} +{}'.format(player.str, Nstr, player.dex, Ndex, player.int, Nint))
player.str+=Nstr
player.dex+=Ndex
player.int+=Nint
print('Exp: '+str(player.xp))
print('To the next level: {}%'.format(int((player.xp/player.lvl_next)*100)))
print('Next:', player.lvl_next)
But I don't know why it just does not work.
I've tried to simplify my code because well maybe thats how i'll find the problem. But it just keeps shoving me this error.
Traceback (most recent call last):
File "F:\2XK_\Coding\Python\Python_Battle\Ulfberht\leveling_system.py", line 99, in <module>
pl_level()
File "F:\2XK_\Coding\Python\Python_Battle\Ulfberht\leveling_system.py", line 11, in pl_level
while player.xp>=player.lvl_next:
AttributeError: type object 'player' has no attribute 'xp'
Even tho you can see that in init there is self.xp.
So how can I fix this?
Use that like self.px inside other methods or else if you want to use like that only make it player().px instead of player.px.As your class needs to be to initialized first before using any of its variables or methods.
Better to access class variables in same class by using self as good practice.
I am coding for to workout this question
Question
Using the concept of object oriented programming and inheritance, create a super class named Computer, which has two sub classes named Desktop and Laptop.
Define two methods in the Computer class named getspecs and displayspecs, to get the specifications and display the specifications of the computer.
You can use any specifications which you want.
The Desktop class and the Laptop class should have one specification which is exclusive to them for example laptop can have weight as a special specification.
Make sure that the sub classes have their own methods to get and display their special specification.
Create an object of laptop/ desktop and make sure to call all the methods from the computer class as well as the methods from the own class.
My solution for this is
class Computer:
def __init__(self, ram, gfx, backlit):
self.ram = ram
self.gfx = gfx
self.backlit = backlit
def getspecs(self):
self.ram = (input('RAM: '))
self.gfx = (input('GFX: '))
self.backlit = (input('Backlit: '))
def displayspecs(self):
print('RAM: ', self.ram, 'GFX: ', self.gfx, 'Backlit: ', self.backlit)
class Laptop(Computer):
def __init__(self, weight):
self.weight = weight
def getspecs_laptop(self):
self.weight = (input('Enter Weight: '))
def displayspecs_laptop(self):
print('Weight: ', self.weight)
class Desktop(Computer):
def __init__(self, size):
self.size = size
def getspecs_desktop(self):
self.size = (input('Enter Size: '))
def displayspecs_desktop(self):
print('Size:', self.size)
Computer1 = Laptop
Computer1.getspecs(1)
Computer1.getspecs_laptop(2)
Computer1.displayspecs(3)
Computer1.displayspecs_laptop(5)
Computer1.displayspecs(4)
Computer2 = Desktop
Computer2.getspecs(6)
Computer2.getspecs_desktop(7)
Computer2.displayspecs(9)
Computer2.displayspecs_desktop(99)
OUTPUT -
"D:\Coding\Python Exercises\Ass6\venv\Scripts\python.exe" "D:/Coding/Python Exercises/Ass6/Demo1.py"
RAM: 1
Traceback (most recent call last):
File "D:/Coding/Python Exercises/Ass6/Demo1.py", line 43, in <module>
Computer1.getspecs(1)
File "D:/Coding/Python Exercises/Ass6/Demo1.py", line 9, in getspecs
self.ram = (input('RAM: '))
AttributeError: 'int' object has no attribute 'ram'
Process finished with exit code 1
What is the mistake I am doing?
What needs to be given in the parent-thesis in the defined
objects?
Computer1.getspecs(here What needs to be added?)
When I run it without giving any value in it, I get error
TypeError: getspecs() missing 1 required positional argument: 'self'
There are far too many errors in this code to give you a simple answer. However, I can help with the first few:
Most of all, you wrote a lot of code without testing any of it. As a result, you now have to fix several errors at once to get any useful output. Comment out your main program for now. Instead, test your Computer class before you try to work with a Laptop or Desktop.
You need to instantiate an object of the class. Then you can use the class methods the way you want. In particular, Computer1 = Laptop(3.5) will give you a Laptop object of some weight.
Note that each of your __init__ methods has at least one required argument. Comment those out until you get used to working with basic objects.
I hope this will allow you to make some progress with your code.
I think it’s best if I explain what I want to do, first:
I am currently developing a testing framework using Python, pytest and Pyro4. It is indented to test software running on hardware prototypes. The developer/tester is executing the test script on his PC locally using pytest. In the test script, actions are executed using Pyro4 proxy objects which connect to a Pyro4 server (daemon) running on a Raspberry Pi. The implementation on the Raspberry Pi adapts various sensors and relays that are connected to the device under test, represented as objects, which are then passed to the Pyro4 daemon.
Here is a simplified example of how a test script could look like.
What it does: Press button x and measure if LED y lights up.
#pytest.fixture(scope="module")
def test_components():
# initialize a dict of pyro proxy objects that represent a hardware component, controlled by the Raspberry Pi
a_dict = {}
a_dict['button_x'] = Pyro4.Proxy("PYRO:button_x#192.168.1.2:1234")
a_dict['status_led'] = Pyro4.Proxy("PYRO:status_led#192.168.1.2:1234")
return a_dict
def test_functionality_button_led(test_components):
test_components['button_x'].set_for(0.5) # presses button x / enables relay x for 0.5 seconds
time.sleep(1)
assert test_compontents['status_led'].get_level() > 0 # assert that led is on
Now, to my initial question: After each test run, i want to have a log file that shows the function calls, their input values and their return values. So it should look roughly like this:
0.1: test_components('button_x').set_for(0.5) [None]
0.2: time.sleep(1) [None]
1.2: assert test_compontents('status_led').get_level() [1] > 0
I had two options in mind but was not able to archieve this:
Leveraging pytest
I was hoping to find some switch or plugin (for example pytest-logging) which would help me do this, but i simply could not find anything to archieve this.
Leveraging Pyro
This is where i got a bit farer. I was hoping to be able to subclass Pyro4 Proxy (the client) stuff to get this done. I subclassed Pyro4.Proxy and reimplemented the __getattr__ method, which is called to get the methods from the remote object at runtime. Using the name attribute, i can now at least detect when and which method is called, but i can still not get the return and input values.
class ImprovedProxy(Pyro4.Proxy):
def __getattr__(self, name):
print(name)
return = Pyro4.Proxy.__getattr__(self, name)
To get the input and output values i would need to subclass and replace the _RemoteMethod class, which is returned by Pyro4.Proxy.__getattr__(self, name) but i couldn't even run the original code from Pyro4.Proxy.__getattr__(self, name) in my ImprovedProxy.__getattr__(self, name) without loads of errors, see for yourself:
class ImprovedProxy(Pyro4.Proxy):
def __getattr__(self, name):
if name in Pyro4.Proxy.__pyroAttributes:
# allows it to be safely pickled
raise AttributeError(name)
if config.METADATA:
# get metadata if it's not there yet
if not self._pyroMethods and not self._pyroAttrs:
self._pyroGetMetadata()
if name in self._pyroAttrs:
return self._pyroInvoke("__getattr__", (name,), None)
if config.METADATA and name not in self._pyroMethods:
# client side check if the requested attr actually exists
raise AttributeError("remote object '%s' has no exposed attribute or method '%s'" % (self._pyroUri, name))
if self.__async:
return _AsyncRemoteMethod(self, name, self._pyroMaxRetries)
return _RemoteMethod(self._pyroInvoke, name, self._pyroMaxRetries)
The Traceback was:
File "C:\...\client.py", line 38, in __getattr__
if name in Pyro4.Proxy.__pyroAttributes:
AttributeError: type object 'Proxy' has no attribute '_ImprovedProxy__pyroAttributes'
Not sure why the name of my subclass is prepended here and after fiddling with the code for a while, i am not sure if this is the right way.
Is there a better way to solve this? As a last resort i could log actions on the server and send it to the client, but i would like to avoid this, one reason being that i have multiple of these test adapters running which would then require precise time syncronisation.
I hope i could explain this well enought. Looking forward to your replies.
The reason you're seeing '_ImprovedProxy__pyroAttributes' in your traceback is because your code is trying to access a private attribute on the base proxy. First line in your __getattr__ method. Python is doing its standard name mangling, like it does for all attributes starting with a double underscore, to make it a "private" attribute. You are not supposed to access this attribute.
Now, the actual solution to your issue is, however, simple, I think: override the proxy's _pyroInvoke method instead. This is what eventually gets called, and it is the logic that is doing the actual remote method call. I think it provides all the arguments that you need:
def _pyroInvoke(self, methodname, vargs, kwargs, flags=0, objectId=None):
"""perform the remote method call communication"""
...
I'm three weeks into learning Python, via "Learn Python the Hard Way" -- since I'm not new to programming, I've been able to progress pretty rapidly through the first half of the book, until I started to get into the OOP portion with classes and objects. Now I'm having a lot of trouble; though I think I've understood the ideas behind these object concepts, I've clearly got something obscurely wrong with my code (I'm using Python 2.7.6, which appears to be part of gcc 4.8.2, in Kubuntu 14.04, kept up to date).
I'm working on Exercise 43, trying to create an adventure game starting from the author's skeleton class definitions. I did pretty well with the first game design (using Python the way I'd have used Basic for the same task, years ago), but I've been about ten console hours trying to beat the latest error in the OOP game; I've read dozens of searched solutions (here and elsewhere) without finding anything that precisely applies. I've pared the code down as much as possible, and I'm still seeing the same error (which I'll paste after the code -- warning, this is still almost 100 lines):
# Python the Hard Way -- Exercise 43: Basic Object-Oriented Analysis and Design
# received as skeleton code, try to make it into a playable game
# my comment: Much harder than designing from scratch! Author's
# design method (or that appropriate for OOP) differs greatly from
# what I'm used to.
from sys import exit
class UserEntry (object):
def __init__(self):
pass
def get_input (self):
# initialize variable for trimmed command list
short_list = []
# accept input, break at spaces, and reverse for parsing
command = raw_input ('> ')
command_list = command.split (' ')
command_list.reverse ()
# parse command here
for i in reversed (xrange (len(command_list))):
if ((command_list [i] in a_game.act.keys()) or
(command_list [i] in a_game.obj.keys())):
short_list.append (command_list.pop())
else:
command_list.pop()
# return parsed_command
if len(short_list) == 1 and short_list[0] in a_game.act.keys():
short_list.append (' ')
return short_list
class Scene (object):
def enter(self):
pass
class Engine (object):
def __init__(self, scene_map):
self.scene_map = scene_map
self.act = {
'inventory' :self.inventory,
'look' :self.look,
}
self.obj = {
'blaster' :'',
'corridor':'',
'gothon' :'',
}
def inventory(self):
pass
def look (self):
pass
def opening_scene(self):
# introduce the "plot"
print "Game intro",
def play(self):
entry = UserEntry()
self.opening_scene()
a_map.this_scene.enter()
class CentralCorridor(Scene):
def enter(self):
print "Central Corridor"
class Map(object):
def __init__(self, start_scene):
scenes = {
'central corridor': CentralCorridor,
}
this_scene = scenes[start_scene]()
print this_scene
a_map = Map('central corridor')
a_game = Engine(a_map)
a_game.play()
When I try to run this, I get the following:
$ python ex43bug.py
<__main__.CentralCorridor object at 0x7f13383c8c10>
Game intro
Traceback (most recent call last):
File "ex43bug.py", line 89, in <module>
a_game.play()
File "ex43bug.py", line 70, in play
a_map.this_scene.enter()
AttributeError: 'Map' object has no attribute 'this_scene'
Clearly, something is preventing this_scene from being visible to other classes/methods; I just don't get what it is. I don't have indention problems (that I can see), I don't have circular imports (in fact, I'm importing only a single module, for the exit command). The first print line is generated by print this_scene within instance a_map; I should get Game intro and then Central corridor as, first, Engine.opening_scene and then CentralCorridor.enter execute -- but I never get to the latter, despite apparently successfully instantiating CentralCorridor.
I'm baffled. Why isn't a_map.this_scene visible anywhere but within Map.__init__?
this_scene is only ever a local name in Map.__init__:
def __init__(self, start_scene):
scenes = {
'central corridor': CentralCorridor,
}
this_scene = scenes[start_scene]()
print this_scene
You need to assign it to an attribute on self:
def __init__(self, start_scene):
scenes = {
'central corridor': CentralCorridor,
}
self.this_scene = scenes[start_scene]()
I am writing a Python GTK application for studying some sort of math data. The main script has a single class with only three methods: __INIT__, main(self) for starting the loop and delete_event for killing it.
__INIT__ creates the GUI, which includes a TextBuffer and TextView widgets so that the analysis functions (defined on a separate functions.py module) can output their results to a common log/message area. A relevant extract follows:
include module functions(.py)
(...)
class TURING:
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
(...)
self.logscroll = gtk.ScrolledWindow()
self.logscroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.logbuffer = gtk.TextBuffer()
self.logpage = gtk.TextView(self.logbuffer)
self.logpage.set_editable(gtk.FALSE)
self.logpage.set_cursor_visible(gtk.FALSE)
self.logpage.set_wrap_mode(gtk.WRAP_CHAR)
self.logscroll.add(self.logpage)
self.logscroll.show()
self.logpage.show()
(...)
enditer = self.logbuffer.get_end_iter()
self.logbuffer.insert(enditer, 'Welcome!')
(...)
def main(self):
gtk.main()
if __name__ == "__main__":
turing = TURING()
turing.main()
The intermediate two lines successfully print a welcome message onto the message area defined by self.logpage.
Now, one of the functions in method functions checks whether the database is up to date and if not asks the user to load a new batch of raw data.
One way of doing this is to include a menu item that triggers that function, like this:
item_dataCheck.connect("activate", functions.data_check, '')
functions.data_check runs fine however when it tries to write its output to self.logbuffer an error is thrown complaining that menu item item_dataCheck has no property logbuffer. The offending code is
enditer = self.logbuffer.get_end_iter()
self.logbuffer.insert(enditer, 'Please update the database.')
Obviously the name self is representing the widget that invoked the function, viz., item_dataCheck. My question is how can I from functions.data_check refer directly to logbuffer as a member of the turing instance of the TURING class. I tried to write
enditer = turing.logbuffer.get_end_iter()
turing.logbuffer.insert(enditer, 'Please update the database.')
but that's is not working. I have tried hard to find a solution but with no success.
I believe the matter is quite trivial and I know I still have some serious conceptual problems with Python and OOP, but any help will be heartly appreciated. (I started out card punching Fortran programs on a Burroughs mainframe, so I could count on some community mercy...)
You can provide additional arguments when connecting signals to functions or methods. So your handler functions.data_check can accept extra arguments apart from self:
def data_check(self, logbuffer):
# ...
Then, you can connect with arguments:
item_dataCheck.connect("activate", functions.data_check, logbuffer)
Also, the self parameter is normally used as the first parameter in method definitions. This is a very strong convention so you should use obj or something similar instead. Specially since your signal handlers may be methods too; in which case you could mess it up with its arguments.