"baby" % {"babe": "bebe"}. How could this be useful? - python

The following is a line in a method of a class in Django:
url = self.success_url % self.object.__dict__
Then I tried an example:
>>> "baby" % {"babe": "bebe"}
"baby"
How could this be useful?

% in that case is being used for String Formatting. Because there are no %s in the word "baby", the word is not modified at all.
In your example of the variable url, self.success_url may be something like "hello %s" and self.object.__dict__ may be {"test": "three"}. So simply, that will print:
hello {'test': 'three'}
Do note that if you ever plan on using something like this, you should be using .format():
>>> d = {'baby':'bebe'}
>>> "hello {[baby]}".format(d)
'hello bebe'

You can use Pythons string formatting like so:
print "%(foo)s is good" % {"foo": "bar"}
> bar is good

Your example is useless, but try:
"Hello, my name is %(babe)s" % { 'babe' : 'bebe'}

url can use any of object instance properties:
class X(object):
success_url = "http://goo.gl/%(x)s"
def __init__(self):
self.x = 13
def get_url(self):
return self.success_url % self.object.__dict__
>>> X().get_url()
'http://goo.gl/13'
One can modify these attributes
>>> x = X()
>>> x.x = 174
>>> X().get_url()
'http://goo.gl/174'
So this is useful when url depends on instance attributes (In my example) or instance object attributes (in your one) for example document fields or id, etc.

Related

print object name, when object call a function inside the class

#!/usr/bin/env python
class AA(object):
def __init__(self):
pass
def y(self):
pass
x=AA()
x.y()
When I execute x.y(), I want to print "This is 'x' call me", how should I do it ?
I hope that this will solve your issue
#!/usr/bin/env python
class AA(object):
def __init__(self):
pass
def y(self, name):
self.name = name
print("This is %s call me" % name)
x = AA()
x.y("Tarzan")
Everything is an object in Python, When you create an instance of the class it allocate memory location and that memory location is referenced by your x variable.The only object has memory location, variable doesn't have any memory location. Variable just refer to objects memory location
in your example, X is nothing just reference to your memory location
if define a variable
a = 2
that means a reference to 2
a = 1
that means a now reference to 1
Assigning one variable to another makes a new tag bound to the same value as shown below.
b = a
that means a and b both reference to 1
id() in python return memory location
print id(a)
print id(b)
output
140621897573617
140621897573617
Example 1:
>>> s1 = 'hello'
>>> s2 = 'hello'
>>> id(s1), id(s2)
(4454725888, 4454725888)
>>> s1 == s2 True
>>> s1 is s2 True
>>> s3 = 'hello, world!'
>>> s4 = 'hello, world!'
>>> id(s3), id(s4) (4454721608, 4454721664)
>>> s3 == s4 True
>>> s3 is s4 False
Example 2
>>> class Foo:
... pass
...
>>> bar = Foo()
>>> baz = Foo()
>>> id(bar)
140730612513248
>>> id(baz)
140730612513320
result
Name of object or instance is nothing just reference to memory
location
From #user1334609 's comment:
for example, we have lots of vm instance,vm1=AA(),
vm1.run_cmd("xxxx"), vm2=AA(), vm2.run_cmd("") I want to know which vm
are run some cmd
To know which VM has run the command you can just use the id(self), instead of trying to find the declared variable in code.
Two options you have now to see from which vm, command is running.
Option1: Add a member variable to class. This can give readability.
Option2: Use the id of self in y(). This avoids adding additional variable.
Example code:
#!/usr/bin/env python
class AA(object):
def __init__(self, vmname):
self.whoami = vmname
def y(self):
print "My Name is %s " % self.whoami # Option1
print "My Id is %s " % id(self) # Option2
def main():
vm1=AA("Yoda")
vm1.y()
vm2=AA("Boda")
vm2.y()
vm3=AA("Anakin")
vm3.y()
if __name__ == '__main__':
main()
This gives following output:
My Name is Yoda
My Id is 139725977256656
My Name is Boda
My Id is 139725977256720
My Name is Anakin
My Id is 139725977256784
I have posted a complete solution here:
https://stackoverflow.com/a/49331683/7386061
It works without parameters. For example you could just do:
class AA(RememberInstanceCreationInfo):
def y(self):
print("my name is '"+self.creation_name+"'")
x=AA()
x.y()
out: my name is 'x'

how to get string itself as a variable

I tried in all ways, could not get any solution for it.
I'm stuck in an application, i will give similar example ,
i have some strings,
arg = "school"
arg_2 = "college"
school = "enjoy"
college = "study"
i want to use it in code as below
if ( arg == arg )
\\ want to print content of school here,
else
\\ want to print content of college here,
can i make it with the help of string 'arg' only? i don't want to use the name of string 'school' here.
is there any method to do that?
You can use locals to do this
>>> arg = "school"
>>> arg_2 = "college"
>>> school = "enjoy"
>>> college = "study"
>>> locals()[arg]
'enjoy'
>>> locals()[arg_2]
'study'
So you could simply print a statement like
>>> "{} at {}".format(locals()[arg], arg)
'enjoy at school'
>>> "{} at {}".format(locals()[arg_2], arg_2)
'study at college'
PS: doing arg == arg is completely redundant, it will always evaluate to True
I am assuming that your goal is to get indirect access to values. In that case, consider putting your variables in a class or a dictionary. Here is an example of the class approach:
class mydata(object):
arg = "school"
arg_2 = "college"
school = "enjoy"
college = "study"
def value_of_value(self, s):
return getattr(self, getattr(self, s))
x = mydata()
print 'arg->', x.value_of_value('arg')
print 'arg_2->', x.value_of_value('arg_2')
This produces:
arg-> enjoy
arg_2-> study

Looping over one dict. key() in python

I have two methods here that don't seem to want to talk to eachother. I think the way I use my dictionary is slightly wrong and I've probably confused myself a bit:
def load(self, msg):
loadState = {'foo1' { 'FirstObject':1, 'SecondObject':2 }, 'foo2' { 'FirstObject':3, 'SecondObject':4 }}
foo_objects = loadState.keys()
for name in foo_objects:
if name == 'foo1':
ValueTuple = loadState[foo_objects[0]]
elif name == 'foo2':
ValueTuple = loadState[foo_objects[1]]
self.program.supervisor.setI2c( ValueTuple, foo = name ) #This is where I think it goes wrong
Then to store these values, I pass them over to this method which was working previously, put it doesn't like the new method above:
def setI2c( self, ValueTuple, foo=None ) :
for name in foo :
object = self.objects[name]
for name in ValueTuple :
register = reg(name)
register.value = regNameValueTuple[name]
EDIT: Part where I went wrong:
self.program.supervisor.setI2c( ValueTuple, foo = [name] )
Your load message can be simplified to:
def load(self, msg):
loadState = {'foo1' { 'FirstObject':1, 'SecondObject':2 }, 'foo2' { 'FirstObject':3, 'SecondObject':4 }}
for name, value in foo_objects.iteritems():
self.program.supervisor.setI2c(value, foo=name)
Here, foo is a string, one of the keys in loadState.
You then loop over foo in setI2c, where foo is still as string. That means you are iterating over the individual characters:
>>> foo = 'foo1'
>>> for name in foo:
... print name
...
f
o
o
1
You don't need that loop at all, you most likely wanted this:
def setI2c(self, value_dict, foo=None):
object = self.objects[foo]
for name in value_dict:
register = reg(name)
register.value = regNameValueTuple[name]
but you don't actually use object anywhere in your code, so that line could be removed altogether.
If setI2c() always expects foo to be a list of names, then you should pass in a list in load:
self.program.supervisor.setI2c(value, foo=[name])

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 can I combine a switch-case and regex in Python

I want to process a string by matching it with a sequence of regular expression. As I'm trying to avoid nested if-then, I'm thinking of switch-case. How can I write the following structure in Python? Thank you
switch str:
case match(regex1):
# do something
case match(regex2):
# do sth else
I know Perl allows one to do that. Does Python?
First consider why there is no case statement in Python. So reset you brain and forget them.
You can use an object class, function decorators or use function dictionaries to achieve the same or better results.
Here is a quick trivial example:
#!/usr/bin/env python
import re
def hat(found):
if found: print "found a hat"
else: print "no hat"
def cat(found):
if found: print "found a cat"
else: print "no cat"
def dog(found):
if found: print "found a dog"
else: print "no dog"
st="""
Here is the target string
with a hat and a cat
no d o g
end
"""
patterns=['hat', 'cat', 'dog']
functions=[hat,cat,dog]
for pattern,case in zip(patterns,functions):
print "pattern=",pattern
case(re.search(pattern,st))
C style case / switch statements also "fall through, such as:
switch(c) {
case 'a':
case 'b':
case 'c': do_abc();
break;
... other cases...
}
Using tuples and lists of callables, you can get the similar behavior:
st="rat kitten snake puppy bug child"
def proc1(st): print "cuddle the %s" % st
def proc2(st): print "kill the %s" % st
def proc3(st): print "pick-up the %s" % st
def proc4(st): print "wear the %s" % st
def proc5(st): print "dispose of the %s" %st
def default(st): print "%s not found" % st
dproc={ ('puppy','kitten','child'):
[proc3, proc1],
('hat','gloves'):
[proc3, proc4],
('rat','snake','bug'):
[proc2, proc3, proc5]}
for patterns,cases in dproc.iteritems():
for pattern in patterns:
if re.search(pattern,st):
for case in cases: case(pattern)
else: default(pattern)
print
This gets the order for the found item correct: 1) pick up child, cuddle the child; 2) kill the rat, pick up the rat... It would be difficult to do the same with a C switch statement in an understandable syntax.
There are many other ways to imitate a C switch statement. Here is one (for integers) using function decorators:
case = {}
def switch_on(*values):
def case_func(f):
case.update((v, f) for v in values)
return f
return case_func
#switch_on(0, 3, 5)
def case_a(): print "case A"
#switch_on(1,2,4)
def case_b(): print "case B"
def default(): print "default"
for i in (0,2,3,5,22):
print "Case: %i" % i
try:
case[i]()
except KeyError:
default()
To paraphrase Larry Wall, Tom Christiansen, Jon Orwant in Programming Perl regarding understanding context in Perl:
You will be miserable programming Python until you use the idioms that are native to the language...
A quick search shows a similar question asked earlier with multiple work arounds. May favorite solution from that one is by Mizard
import re
class Re(object):
def __init__(self):
self.last_match = None
def match(self,pattern,text):
self.last_match = re.match(pattern,text)
return self.last_match
def search(self,pattern,text):
self.last_match = re.search(pattern,text)
return self.last_match
gre = Re()
if gre.match(r'foo',text):
# do something with gre.last_match
elif gre.match(r'bar',text):
# do something with gre.last_match
else:
# do something else
You are looking for pyswitch (disclaimer: I am the author). With it, you can do the following, which is pretty close to the example you gave in your question:
from pyswitch import Switch
mySwitch = Switch()
#myswitch.caseRegEx(regex1)
def doSomething(matchObj, *args, **kwargs):
# Do Something
return 1
#myswitch.caseRegEx(regex2)
def doSomethingElse(matchObj, *args, **kwargs):
# Do Something Else
return 2
rval = myswitch(stringYouWantToSwitchOn)
There's a much more comprehensive example given at the URL I linked. pyswitch is not restricted to just switching on regular expressions. Internally, pyswitch uses a dispatch system similar to the examples others have given above. I just got tired of having to re-write the same code framework over and over every time I needed that kind of dispatch system, so I wrote pyswitch.
Your question regarding Perl style switch statements is ambiguous. You reference Perl but you are using a C style switch statement in your example. (There is a deprecated module that provides C style switch statements in Perl, but this is not recommended...)
If you mean Perl given / when type switch statements, this would not be trivial to implement in Python. You would need to implement smart matching and other non-trivial Perl idioms. You might as well just write whatever in Perl?
If you mean C style switch statements, these are relatively trivial in comparison. Most recommend using a dictionary dispatch method, such as:
import re
def case_1():
print "case 1"
return 1
def case_2():
print "case 2"
return 2
def case_3():
print "case 3"
return 3
def default():
print "None"
return 0
dispatch= {
'a': case_1,
'g': case_2,
'some_other': case_3,
'default': default
}
str="abcdefg"
r=[dispatch[x]() if re.search(x,str) else dispatch['default']()
for x in ['a','g','z'] ]
print "r=",r
If you're avoiding if-then, you can build on something like this:
import re
# The patterns
r1 = "spam"
r2 = "eggs"
r3 = "fish"
def doSomething1():
return "Matched spam."
def doSomething2():
return "Matched eggs."
def doSomething3():
return "Matched fish."
def default():
return "No match."
def match(r, s):
mo = re.match(r, s)
try:
return mo.group()
except AttributeError:
return None
def delegate(s):
try:
action = {
match(r1, s): doSomething1,
match(r2, s): doSomething2,
match(r3, s): doSomething3,
}[s]()
return action
except KeyError:
return default()
Results
>>> delegate("CantBeFound")
0: 'No match.'
>>> delegate("spam")
1: 'Matched spam.'
>>> delegate("eggs")
2: 'Matched eggs.'
>>> delegate("fish")
3: 'Matched fish.'

Categories