What is the indented lines directly below try: called/reffered to? I have heard "the body of try:" and "the expression of try:". Please clarify. (See user - poke´s - answer)
What is try:, except:, while: etc. reffered to? Like True and False are reffered to as "statements". (See user - poke´s - answer)
Is there any reason to change function1 into function2. The only difference between them is ValueError. The functions are only supposed to force the user to input an integer. (See user - poke´s - answer)
function1
def get_integer(LIMIT_PROMPT):
while True:
try:
return int(input(LIMIT_PROMPT))
except:
pass
I have seen lots of except statement: and in the body/expression there is a piece of code that does something if an error occured in the body/expression of try:
I have used this particular function in two programs and have not run into any trouble.
function2
def get_integer(LIMIT_PROMPT):
while True:
try:
return int(input(LIMIT_PROMPT))
except ValueError:
pass
Like True and False are referred to as "statements"
True and False are both variables referring to singleton values of the bool type. As variables, they are atomic expressions.
try, except, while etc. are statements, or more accurately, compound statements because they contain a group of other statements. Usually you would refer to that group of statements as a block, as in other languages they are encapsulated within block creating tokens (e.g. { and }). In the Python specification, they are being referred to as suite.
The suites of each compound statement does not really have a special name, so I guess you could just call them “try suite”, “except suite” etc., or “try block” and “except block”.
Is there any reason to change this function into this (the only change is ValueError)
Usually, when you check for exceptions, you should be as specific as possible. If you know that what you do within the try block can throw an exception of type X, then catch/except exception X only.
Not specifying a type will make the except catch any exception including those you might not know of that they could be thrown there, so you would lose useful information there. There are a lot questions on SO that already handle that topic, so I’ll just lead you to a random one I just found. Exception management is language agnostic, so you can just apply what you read to Python.
Related
As stated in the title, how? I'm really struggling with understanding the documentation as there are no examples of anything. How do I define something like a VoiceState, Member, VoiceChannel, etc...
Running on tutorials is fine until you have to start consulting the documentation for something specific, at which point it becomes really frustrating when you have no idea how to define objects or use certain commands...
A lot of this will come from experience, so don't be discouraged if it takes a while to get the hang of! I know that the docs can be a bit daunting, but I'll try to help as best I can by giving a couple of examples.
When making a discord bot, usually you're going to be getting information based off of arguments and ctx (context).
First I'll start off with some general examples, and then I'll move onto how to use these when working with d.py.
Parameters and args
When you create functions in python, you can define parameter types:
def my_func(a: int):
return a + 5
What this does is assume that the args passed into my_func will be integers, and therefore behave as ints too:
my_func(1)
Will return, as you might expect, 6.
However, when you try to pass in something like so:
my_func("1")
You'll get a TypeError which complains about concatenating str and int. Additionally, you can see the differences in an object when you list its attributes like so: dir(obj)
When applying this same concept to a command:
#bot.command()
async def cmd(ctx, member: discord.Member):
await ctx.send(f"Hello, {member.mention}!")
But when using commands, what it does is it's able to get a member based off of an attribute you enter, such as the member's ID or name. The member that it finds, then has all of the discord.Member object's attributes.
This means you'll be able to access things such as the member's roles, which return a list containing each role as a discord.Role object, which from there, you can get the role's attributes, and so on and so forth.
SIDE-NOTE:
Another way of getting objects in d.py is by using discord.utils. It takes in an iterable, e.g. a list, as the first argument, and then after that it takes keyword arguments, such as name, id, colour, or any attributes of an abc to return an object.
Example:
#bot.command()
async def getrole(ctx):
role = discord.utils.get(ctx.author.roles, name="Very Special Role!", mentionable=True)
await ctx.send(f"Look at you with your {role.mention} How classy!")
And that will iterate through each of the message sender's roles, looking for the name (case sensitive) Very Special Role! which is mentionable, and it will send the message using one of the role's attributes; mention.
Context
With commands, the first argument you're going to be passing in is Context, which by convention is denoted as ctx.
As shown in the link, it has a range of attributes, which revolve mostly around the command's origin, author, and all other details about it etc.
#bot.command()
async def hello(ctx):
await ctx.send(f"Hello, {ctx.author.name}!")
In the command there, I'm using the coroutine from context called send(), which is used for sending messages.
And in the context of the command, it'll be sending it to the same channel, which is how that works.
Also, an example of some commonly used superfluous code:
ctx.message.channel.send("some message")
ctx.message.author.send("some dm")
can be respectively turned into:
ctx.send("some message")
ctx.author.send("some dm")
But how do you know where you can send() a message to? Well that brings us onto the next part:
Abstract Base Classes
These are, what I'm assuming you were talking about when you were on about defining objects. They are the base templates for objects to inherit from - for example, TextChannel has inherited all of Messageable's attributes (except connectable, which is only inherited by discord.VoiceChannel.channel.
I'll use abc.Messageable as an example. In the link, it gives us examples of some Messageable objects, i.e. where you can send messages to, and these are objects such as TextChannels, Members etc.
Occasionally I see someone miss out an await or not know when to add them, or add them too often. You'll know when to add one, as the docs will state whether the function is a couroutine or not, for example:
That's how you know what you can do with each object - think of these as templates for the objects you get within discord, not something that you define!
If you need any further clarification or if you noticed any mistakes with my answer, please let me know.
References:
commands.Command() - decorator for commands
commands.Context
Coroutines
discord.Member
Member.roles
discord.Role
Context.send()
discord.TextChannel
discord.utils
discord.abc
This is the property definition I use to lazy load the element attribute of my Element class, borrowed from This post on Python lazy loading.
#property
def element(self):
if not hasattr(self, "_element"):
self._element = self.wait.wait_for_element_to_be_visible(self.locator)
return self._element
It looks for the attribute _element if it doesn't find it then it goes and looks for it. If the attribute is there then it just returns the attribute without looking for it as its already been loaded in.
I've changed the if to be:
if self._element is None:
self._element = self.wait.wait_for_element_to_be_visible(self.locator)
return self._element
Is it more pythonic to see if the attribute exists, or to set _element to None in the __init__ method and then check for that instead?
Doing it the second way also seems better for debugging purposes in IntelliJ as there seems to be a strange loading issue that freezes the tests if I expand my Element object and it starts introspection to display attributes and their values.
My definition of a pythonic solution is the one that's most likely to help a future maintainer understand what's going on when they come across this code (most times it's the same person who wrote it but long after they have it in their memory). Here's some things I might ask myself if I was coming in cold.
1. hasattr
self._element is not in __init__, is this because it's set somewhere else?
Every access checks for the attribute, does that mean it's expecting it to be deleted at some point so it can refresh? Why else is it checked every time?
hasattr will search up the chain of MRO, are we actually looking for something?
2. is None
Found self._element in __init__ being set to None. Am I allowed to set it to None again to get fresh values? The _ in _element is hinting no.
2a. is _Missing
If None is a valid result, use a sentinel instead.
class _Missing:
pass
def __init__():
self._element = _Missing
3. One shot descriptor
Property produces what is known as a data descriptor. It will ignore attributes of the instance and go straight to the classes dictionary (otherwise __set__ won't be able to do it's thing). Here we make our own non-data descriptor (only defines __get__), which won't skip the instances dictionary. This means the instances attribute can be set. Deleting the instance attribute will result in a refreshed value on the next invocation.
class LazyLoadElement:
def __get__(self, instance, owner):
instance.element = instance.wait.wait_for_element_to_be_visible(instance.locator)
return instance.element
class MyClass:
element = LazyLoadElement()
What's the intention of the LazyLoadElement? Name says it all
Can it refresh to another value? Nope, it's set after the first call and removes itself.
Pythonic is a little arm wavy because it needs to make assumptions about who is reading the code at a future date. Out of the 2 original options, number 2 seems most likely to get maintainers up to speed. 3 is my fav though, mainly because once it's loaded there's no more function calls.
I've inherited a lotus notes application and one of the things that really irks me is every function/sub/property has onerror statements and errorhandler labels that aside from typos all do the exact same thing. Additionally, and unfortunately this application has gone through several revisions and some errorhandler: labels have revisions where as other don't. I'd like to standardize and centralize this behavior.
Is there a way to have a single error handler for a given document, where if an error is raised anywhere in the document, that particular error handler is called?
Thank you,
You can have one error handler per script execution. You cannot have one global to a document. Each event that fires in a document results in a new script execution.
That said, it is generally advantageous to have one error handler per function, but that advantage is lost if they are actually exactly the same. The better practice is to customize them so that each error handler records the name of the current function. (Of course, due to copy/paste laziness, this is frequently more effective in theory than in practice.)
If you have an On Error Goto SomeLabel statement (where SomeLabel is whatever label the code actually uses), the label must exist in the same Sub/Function that contains that statement so, technically, you need a separate handler for each Sub/Function.
However, some things might simplify matters...
If one Sub/Function calls another Sub/Function, and the inner one doesn't have an error handler but the outer one (the caller) does, then an error in the inner Sub/Function will be caught by the handler in the caller.
This setup gives you less information (you can't get the line number on which the error occurred in the inner Sub/Function), but it might be helpful if you have any Subs/Functions that you're sure either can't produce an error, or only have one line on which an error could occur.
If you have some static message-text or logging which is identical in many error handlers, you could have a Sub/Function in the Form Globals (or in a script library to absolutely minimise code duplication) that contains the static parts of the error handlers, and takes arguments for the variable parts (error message, line number, and Sub/Function name).
Finally, this code will produce the name of the current Sub/Function and makes it easier to use the same error handler in many places, as long as the code declarations contain %include "lsconst.lss" or you use a script library containing the same %include statement:
GetThreadInfo(LSI_THREAD_PROC)
Another function, LSI_Info, can also give you the name of the current Sub/Function, but isn't supported by IBM, and should be avoided.
In JVM languages there is a data type called Optional which says value can be Null/None. By using the data type of a function as Option(for example Option(Int)). Calling statement of function can take action.
How does one implement a similar approach in Python.
I want to create a function and the return value of function should tell me
1. Function was successful so I have a value returned.
2. Function was not successful and so there is nothing to return.
I also wanted to tackle this problem and made a library called optional.py to do so. It can be installed using pip install optional.py. It is fully test covered and supports python2 and python3. Would love some feedback, suggestions, contributions.
To address the concerns of the other answer, and to head off any haters, yes, raising exceptions is more idiomatic of python, however it leads to ambiguity between exceptions for control-flow and exceptions for actual exceptional reasons.
There are large discussions about preventing defensive programming which mask the core logic of an application and smart people on both sides of the conversation. My personal preference is towards using optionals and so I provided the library to support that preference. Doing it with exceptions (or returning None) are acceptable alternatives, just not my preference.
To your original question: Raise an exception instead of returning None. This is an idiom in Python and therefore well understood by users. For example
def get_surname(name):
if name == "Monty":
return "Python"
else:
raise KeyError(name)
You'll see this usage pattern a lot in Python:
try:
print(get_surname("foo"))
except KeyError:
print("Oops, no 'foo' found")
Based on your feedback, it also seemed like you wanted to make sure that certain return values are actually used. This is quite tricky, and I don't think there is an elegant way to enforce this in Python, but I'll give it a try.
First, we'll put the return value in a property so we can track if it has indeed been read.
class Result(object):
def __init__(self, value):
self._value = value
self.used = False
#property
def value(self):
self.used = True # value was read
return self._value
Secondly, we require that the Result object must be retrieved in a with-block. When the block is exited (__exit__), we check if the value has been read. To handle cases where a user doesn't use the with-statement, we also check that the value has been read when it is being garbage collected (__del__). An exception there will be converted into a warning. I usually shy away from __del__ though.
class RequireUsage(object):
def __init__(self, value):
self._result = Result(value)
def __enter__(self):
return self._result
def __exit__(self, type, value, traceback):
if type is None: # No exception raised
if not self._result.used:
raise RuntimeError("Result was unused")
def __del__(self):
if not self._result.used:
raise RuntimeError("Result was unused (gc)")
To use this system, simply wrap the return value in RequireUsage like so:
def div2(n):
return RequireUsage(n/2)
To use such functions, wrap them in a block and extract the value:
with div2(10) as result:
print(result.value)
If you don't invoke result.value anywhere, you will now get an exception:
with div2(10) as result:
pass # exception will be thrown
Likewise, if you just call div2 without with at all, you will also get an exception:
div2(10) # will also raise an exception
I wouldn't particularly recommend this exact approach in real programs, because I feel it makes usage more difficult while adding little. Also, there are still edge-cases that aren't covered, like if you simply do res = div2(10), because a held reference prevents __del__ from being invoked.
One approach would be to return either () or (<type>,) (int in your case). You could then come up with some helper functions like this one:
def get_or_else(option: tuple, default):
if option:
return option[0]
else:
return default
One benefit of this approach is that you don't need to depend on a third-party library to implement this. As a counterpart, you basically have to make your own little library.
This question is with reference to the Cymbol code from the book (~ page 143) :
int t = ctx.type().start.getType(); // in DefPhase.enterFunctionDecl()
Symbol.Type type = CheckSymbols.getType(t);
What does each component return: "ctx.type()", "start", "getType()" ? The book does not contain any explanation about these names.
I can "kind of" understand that "ctx.type()" refers to the "type" rule, and "getType()" returns the number associated with it. But what exactly does the "start" do?
Also, to generalize this question: what is the mechanism to get the value/structure returned by a rule - especially in the context of usage in a listener?
I can see that for an ID, it is:
String name = ctx.ID().getText();
And as in above, for an enumeration of keywords it is via "start.getType()". Any other special kinds of access that I should be aware of?
Lets disassemble problem step by step. Obviously, ctx is instance of CymbolParser.FunctionDeclContext. On page 98-99 you can see how grammar and ParseTree are implemented (at least the feeling - for real implementation please see th .g4 file).
Take a look at the figure of AST on page 99 - you can see that node FunctionDeclContext has a several children, one labeled type. Intuitively you see that it somehow correspond with function return-type. This is the node you retrieve when calling CymbolParser.FunctionDeclContext::type. The return type is probably sth like TypeContext.
Note that methods without 'get' at the beginning are usually children-getters - e.g. you can access the block by calling CymbolParser.FunctionDeclContext::block.
So you got the type context of the method you got passed. You can call either begin or end on any context to get first of last Token defining the context. Simply start gets you "the first word". In this case, the first Token is of course the function return-type itsef, e.g. int.
And the last call - Token::getType returns integral representation of Token.
You can find more information at API reference webpages - Context, Token. But the best way of understanding the behavior is reading through the generated ANTLR classes such as <GrammarName>Parser etc. And to be complete, I attach a link to the book.