how to make a method for a string in python - python

Im looking to create something that I can use to check if a string meets a condition like so:
var = "hello"
check = var.checkconditions()
Im just curious as to if its possible as I have never seen it done before.
How would the function/whatever I need to use be set out?

String is a build in class/object and can not be changed. However you can make a personal new class:
class str_class:
def __init__ (self, str):
self.str = str
def checkconditions(self):
# Enter your conditions
var = str_class('hello')
check = var.checkconditions()
Or you could simply make a funtion that takes the string as input and outputs if the condition is met or not:
def checkconditions(str):
# Enter conditions
var = 'Hello'
check = checkconditions(var)
Edit: From other comments it seems as though it is possible but not recommended.

You can use a Class and then use the method check_conditions.
class Check:
def __init__(self):
pass
def check_conditions(string):
#Do whatever you need in here
print(string)
c = Check
c.check_conditions("hello")
This should hopefully do what you need!

You can't directly add the method to the original type.what you can do is subclass the type like
class mystring(str):
def checkconditions(self):
#condition
and then you can instantiate your new class
var = mystring('hello')
var.checkcondition()
but that's still no too practical, if you want to make it more proper you can do this
import __builtin__
__builtin__.str = mystring
var = str("hello")
check = var.checkconditions()
which achieves most of the effect desired.
Unfortunately, objects created by literal syntax will continue to be of the vanilla type and won't have your new methods/attributes.
var = 'hello'
var.checkconditions()
# Output
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'checkconditions'
"""

Related

Python function asserting value over pre declared value

I have a function (func.py). Structure of which look like this:
database = 'VENUS'
def first_function():
print("do some thing")
def second_function():
print("call third function)
third_function()
def third_function(db = database):
print("do some other thing")
I need to import this function and used the inner defined function. But, I want to use a different key for database. Basically, I want to overwrite database = 'VENUS' and use database = 'MARS' while second function call the third function. is there any way to do this?
Just provide the database name as argument
first_function("MARS")
second_function("MARS")
So the problem here, if I understood correctly, is that the default argument for func.third_function is defined at import time. It doesn't matter if you later modify the func.database variable, since the change will not reflect on the default argument of func.third_function.
One (admittedly hacky) solution is to inject a variable using a closure over the imported function. Example:
file.py:
x = 1
def print_x(xvalue = x)
print(xvalue)
Python console:
>>> import file
>>> file.print_x()
1
>>> file.x = 10
>>> file.print_x() # does not work (as you're probably aware)
1
>>> def inject_var(func_to_inject, var):
def f(*args, **kwargs):
return func_to_inject(var, *args, **kwargs)
return f
>>> file.print_x = inject_var(file.print_x, 10)
>>> file.print_x() # works
10
So using the inject_var as written above, you could probably do:
func.third_function = inject_var(func.third_function, "MARS")

Trying to pass list of variable in class and function in object oriented manner

I'm trying to pass variable list in Class and Function in object oriented manner but facing some error, I don't understand what wrong with it and I'm using PyDev in Eclipse
CODE
class Mydetails:
__details = ''
def __init__(self,details): # constructor
#self.__details['country'] = details['country']
self.__details = details
def set_element(self,details):
self.__details = details
def get_list(self,details):
return self.__details
details = ['ABC','DEF','GHI','JKL']
pdetails = Mydetails()
pdetails.set_element(details)
print(pdetails.get_list())
OUTPUT
Traceback (most recent call last):
File "C:\workspace\python\pythonapp\list.py", line 18, in <module>
pdetails = Mydetails()
TypeError: __init__() missing 1 required positional argument: 'details'
in this line:
def __init__(self,details):
you made the init function take a parameter (details), but here:
pdetails = Mydetails()
you arent giving it a parameter! what you probably wanted to do there is:
pdetails = Mydetails(details)
on a side note your def get_list(self,details): function doesn't make sense, why are you passing it a parameter that doesn't get used?
I fixed my code ,It was error in function def get_list(self,details): changed to def get_details(self): because details parameter already copied in self so it not allow the same thats why throwing error, but below code is fixed and work fine with function calling and defined object also correct from previous code.
CODE
class Mydetails:
__details = '' #protected
def __init__(self,details={}): # constructor
self.__details = details
def set_details(self,details): # function
self.__details = details
def get_details(self):
return self.__details
def toString(self):
return 'Welcome {}'.format(self.__details)
new_details = ['xyz','klm','nop']
pdetails = Mydetails()
pdetails.set_details(new_details)
print(pdetails.get_details())
OUTPUT
['xyz', 'klm', 'nop']

Subclassing builtin types -- Python 2 and 3

I have code that looks like the following:
class Token(object):
'''
Resulting from parse
'''
def __new__(cls,text,begin,end,*args,**kargs):
self = super(Token,cls).__new__(cls,*args,**kargs)
return self
def __init__(self,text,begin,end,*args,**kargs):
super(Token,self).__init__(*args,**kargs)
self.text = text
self.begin = begin
self.end = end
class List(Token,list):
pass
class Str(Token,str):
pass
class Int(Token,int):
pass
s = Str('hey there',0,3,'hey there'[0:3])
print(s)
x = Int('55 12',0,2,'55 12'[0:2])
print(x)
Basically what I want to do is to easily create types that are just normal Python types, but with some extra information to them.
Python 2 seems to be OK with the above code, but Python 3 complains
Traceback (most recent call last):
File "simple.py", line 71, in <module>
s = Str('',1,2,'hey')
File "simple.py", line 12, in __init__
super(Token,self).__init__(*args,**kargs)
TypeError: object.__init__() takes no parameters
I think the interpreters would be happy if I did something like
class List(list):
def __init__(self,text,begin,end,*args,**kargs):
list.__init__(*args,**kargs)
But this would mean I would have to repeat something similar for every new class I want to make... and I would rather stay relatively DRY...
Is there a 'proper' way I should handle this situation so that both Python 2 and Python 3 are happy?
Your best bet is to use exception handling here:
def __init__(self,text,begin,end,*args,**kargs):
try:
super(Token,self).__init__(*args,**kargs)
except TypeError:
# Python 3 and the mixed in type is immutable.
# Ignoring this is fine, `__new__` took care of this.
pass
self.text = text
self.begin = begin
self.end = end

How to print a string static member of a class with `yield` from a class method

I am really new to python, so this might be really easy.
I want to print two strings defined in a class as static members with a class method that yields each string.
This is a simplified version of what I am trying to do:
#!/usr/bin/python
import sys
class test:
str1 = "Hello"
str2 = "World\n" #"\n" is needed for the example
def printMe(self):
yield test.str1
yield test.str2
hello = test()
print "Testing initiated:"
sys.stdout.write(hello.printMe())
sys.stdout.write(hello.printMe())
This is the output:
sys.stdout.write(hello.printMe()) TypeError: expected a character
buffer object
You are attempting to use a generator function, read about the yield keyword here
import sys
class Test:
def __init__(self): # it's possible to initialise these attributes in the __init__ method, so they are created on class instantiation(when you did hello = Test())
self.str1 = "Hello"
self.str2 = "World\n" #"\n" is needed for the example
def printMe(self):
for i in [self.str1, self.str2]:
yield i
app = Test()
print "Testing initiated:"
for i in app.printMe():
print i # is there a reason why you can't use print?
If however you want to print the lines one at a time, at specific points in the code, like in your loop you mentioned in the comment:
gen = app.printMe()
then every time you want to print:
gen.next()
this triggers the next yield statement. The generator function effectively 'holds'/remembers it's place until you call next again, until all the yield statements have been yielded.
You should do something like this
for line in hello.printMe():
print line
But really there are a lot of easier ways than using yield statements.
using yield turns your function into a generator. If this is really what you want, you will need to iterate over the generator to get the values:
gen = hello.printMe()
sys.stdout.write(gen.next())
sys.stdout.write(gen.next())
or better:
for prop in hello.printMe():
sys.stdout.write(prop)
Your printMe method is a generator function, which returns an iterable. You need to iterate over it to get the results :
for item in hello.printMe():
print item
You can do this, but I'm using print, hope this helps you:
class test:
str1 = "Hello"
str2 = "World\n" #"\n" is needed for the example
def printMe(self):
yield test.str1
yield test.str2
hello = test()
print "Testing initiated:"
out = hello.printMe()
print(out.next(),end=' ')
print(out.next(),end=' ')

how to get a value-object from another method in python

I can't really understand what I'm doing wrong.. I try to get a value-object from another method.. this is my code
#!/usr/bin/env python
class tracksendi():
def __init__(self):
rospy.on_shutdown(self.shutdown)
rospy.Subscriber('robotis/servo_head_pan_joint',
Float64, self.posisi_ax12_pan)
rospy.Subscriber('robotis/servo_head_tilt_joint',
Float64, self.posisi_ax12_tilt)
rospy.Subscriber('robotis/servo_right_elbow_joint',
Float64, self.posisi_ax12_elbow)
while not rospy.is_shutdown():
self.operasikan_servo()
rate.sleep()
def posisi_ax12_pan(self,pan):
self.posisi_pan_servo = pan.data
return
def posisi_ax12_tilt(self,tilt):
self.posisi_tilt_servo = tilt.data
return
def posisi_ax12_elbow(self,elbow):
self.posisi_elbow_data = elbow.data
return
def ambil_timestamp(self,waktu):
self.data_time_joint_states = waktu.header.stamp
return
def operasikan_servo(self):
# Lengan Kanan
try:
vektor_n_rs = self.posisi_pan_servo - self.posisi_tilt_servo
vektor_re_rs = self.posisi_tilt_servo - self.posisi_elbow_data
except KeyError:
pass
if __name__ == '__main__':
try:
tracksendi()
except rospy.ROSInterruptException:
pass
But, I get this error
vektor_n_rs = self.posisi_pan_servo - self.posisi_tilt_servo
AttributeError: tracksendi instance has no attribute 'posisi_pan_servo'
How that problem solved ???
Note :
rospy.Subscriber('robotis/servo_head_pan_joint', Float64, self.posisi_ax12_pan)
rospy.Subscriber('robotis/servo_head_tilt_joint', Float64, self.posisi_ax12_tilt)
rospy.Subscriber('robotis/servo_right_elbow_joint', Float64, self.posisi_ax12_elbow)
rospy.Subscriber is a line command to insert Float64 data for self.posisi_ax12_pan method, self.posisi_ax12_tilt method and self.posisi_ax12_elbow.
Obviously posisi_ax12_pan and posisi_ax12_tilt called later (after events that you subscribing are occured) than operasikan_servo, so, you should init this attributes - self.posisi_pan_servo and self.posisi_tilt_servo:
def __init__(self):
rospy.on_shutdown(self.shutdown)
self.posisi_pan_servo = 0 # or any number you want
self.posisi_tilt_servo = 0 # or any number you want
#....
The error says self.posisi_pan_servo does not exist. You only seem to define this variable in posisi_ax12_pan(). That means the method posisi_ax12_pan() was not yet called when you tried to access that attribute within operasikan_servo().
I guess that a call to posisi_ax12_* methods should be done before calling operasikan_servo in the constructor.
Looks like you are not executing the method posisi_pan_servo, which initialize the attribute 'posisi_pan_servo'
You should execute it before, trying to get that attribute.
Maybe in the init method you should invoke the method. So try to change from:
rospy.Subscriber('robotis/servo_head_pan_joint', Float64, self.posisi_ax12_pan)
To:
rospy.Subscriber('robotis/servo_head_pan_joint', Float64, self.posisi_ax12_pan(pan))
Passing a the right parameters in that invoke.
But other thing is deep test the rospy.Subscriber method, to check if it is working as you expect

Categories