I've touched on some other languages, but I'm a recent introduction to Python. In the learning process, I picked up some functions that I was interested in compared to other languages and summarized them into 12 items (+ 1 extra).
Each item is almost independent, so you can skip it and read it. (Qiita has a table of contents function, so it's easy to skip reading!)
The operation has been confirmed with the Python 3.5.1 interpreter.
When defining an empty function etc., if it is a language that uses curly braces ({}
) to enclose the body of the function, there is no doubt, but Python does not use parentheses and represents blocks with indentation. So I don't know intuitively what to do.
In conclusion, use the pass
statement.
By the way, although not written here, ** the same is true for empty classes **.
7.4. pass statement (7. simple statement — Python 3.5.1 documentation) http://docs.python.jp/3/reference/simple_stmts.html#the-pass-statement
>>> def foo():
... pass
...
>>> foo()
>>>
Even if I write a blank line with indentation on the second line, the following error occurs. You will get the same error without writing the second line. (In the example, I don't know if it is blank, so I put a comment.)
>>> def foo():
... #
...
File "<stdin>", line 3
^
IndentationError: expected an indented block
>>>
If you write only the appropriate value without writing return
, it seems to work as in the case of the pass
statement, but since the meaning of an empty function is not clear, the method is × I suppose.
>>> def foo():
... pass
...
>>> foo()
>>> def bar():
... 0
...
>>> type(foo())
<class 'NoneType'>
>>> type(bar())
<class 'NoneType'>
>>>
Of course, pass
is a ** statement **, so it cannot be used as an object.
>>> o = pass
File "<stdin>", line 1
o = pass
^
SyntaxError: invalid syntax
>>>
Suppose you have a file called foo / bar.py
that looks like this:
(The description at the beginning is omitted)
import inspect
def baz():
print('module=', __name__, ', func=', inspect.currentframe().f_code.co_name)
def qux():
print('module=', __name__, ', func=', inspect.currentframe().f_code.co_name)
(ʻInspect.currentframe (). F_code.co_name` is the code to get the function name from inside the function.)
Note: It seems that you need to put a file called __init__.py
in thefoo /
directory to use this foo
as a package, as it can be empty.
However, this example works without __init__.py
.
And if you want to call the function in it, it must be the full name. Only the module is imported, not the namespace.
>>> import foo.bar
>>> bar.baz()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'bar' is not defined
>>> foo.bar.baz()
module= foo.bar , func= baz
>>> foo.bar.qux()
module= foo.bar , func= qux
>>>
To import bar
as a namespace from within foo
from foo import bar
will do.
Also, long names are difficult to use, so you can give them an alias with ʻas`.
Of course, you can also combine the two.
>>> from foo import bar
>>> import foo.bar as fb
>>> from foo import bar as b
>>> bar.baz()
module= foo.bar , func=baz
>>> bar.qux()
module= foo.bar , func=qux
>>> fb.baz()
module= foo.bar , func=baz
>>> fb.qux()
module= foo.bar , func=qux
>>> b.baz()
module= foo.bar , func=baz
>>> b.qux()
module= foo.bar , func=qux
>>>
If you use from foo.bar import baz
, you can import the baz
function directly, but it is usually better not to use it because the namespace is confused except for some standard functions. It will be good. (By the way, the qux
function is not imported in this case.)
This section describes how to call your own (local) module, but even if you use the installed library, the difference is that you specify the relative position of the module search path from each directory, but other things Is specified in the same way.
Variables defined in a module that are not closed to blocks are global variables.
(I'm a little unsure about the exact definition of this area. I wonder if the default namespace is the main
module.)
If you newly define a variable with the same name as a global variable in the function, it becomes a local variable. This means that if you try to rewrite (reassign) a global variable in a function, it will be treated as a local variable.
What if I want to rewrite a global variable inside a function?
>>> gv = 'global'
>>> def foo():
... gv = 'local'
... print(gv)
...
>>> gv
'global'
>>> foo()
local
>>> gv
'global'
>>>
You can use the keyword global
to declare that you want to use a global variable in that scope.
>>> gv = 'global'
>>> def foo():
... global gv
... gv = 'reassign'
... print(gv)
...
>>> gv
'global'
>>> foo()
reassign
>>> gv
'reassign'
>>>
bonus:
The functions globals ()
and locals ()
return dictionaries of global variables and local variables, respectively.
There are a lot of global variables, so please actually execute them and check them.
In Python, you can write a value in a formal argument and set a default value.
>>> def foo(arr=[]):
... arr.append('A')
... print(arr)
...
>>> foo(['X', 'Y'])
['X', 'Y', 'A']
>>> foo()
['A']
>>>
So far, I think the behavior is as expected.
Following this, let's call the foo
function with the same arguments omitted.
>>> foo()
['A', 'A']
>>> foo()
['A', 'A', 'A']
>>>
Not what I expected ...
Apparently, in Python, the default value specified for the formal argument is initialized when the function is declared, so the same instance is always used no matter how many times it is called. Therefore, if you specify a mutable object, it will look like this.
If you specify a default value, be sure to specify an immutable object.
In addition, Reference 1 introduced a method of judging by the ʻif statement using
Noneas the default value. (Set the default value to an empty tuple and use the
list` function to list it, isn't it?)
This is no problem, and it's just a normal closure operation as expected.
It looks like it's ready to share a reference to the captured variable.
>>> def foo():
... a = []
... def bar():
... a.append(1)
... def baz():
... a.append(2)
... return a, bar, baz
...
>>> a, bar, baz = foo()
>>> bar()
>>> a
[1]
>>> baz()
>>> a
[1, 2]
>>> bar()
>>> a
[1, 2, 1]
>>>
I want to add a new argument to a function that takes a variable length argument, but even if I add it after it, it is passed as a variable length argument, and if I add it before, compatibility becomes strange, so what should I do?
This may be easier if you know the other languages it supports (I don't know exactly which one).
The answer is ** add an argument with a default value and specify it in "keyword format" when calling **.
You can just see the sample in the built-in function max
.
max
function (2. Built-in functions — Python 3.5.1 documentation)
http://docs.python.jp/3/library/functions.html?highlight=%E7%B5%84%E3%81%BF%E8%BE%BC%E3%81%BF#max
max
function (2. Built-in functions — Python 2.7.x documentation)
http://docs.python.jp/2/library/functions.html?highlight=%E7%B5%84%E3%81%BF%E8%BE%BC%E3%81%BF#max
In the max
function, the ordinal function key
could not be specified in less than Python2.5, but it can be done in Python2.5 or later.
key
can only be specified in keyword format, but it can be extended while maintaining compatibility.
But well, the interface of a function like max
will specify it in keyword format even if it has key
from the beginning.
The following code is an example of declaring a function with an argument structure similar to the max
function.
>>> def foo(*args, opt=None):
... print('args=', args, ', opt=', opt)
...
>>> foo(1, 2, 3)
args= (1, 2, 3) , opt= None
>>> foo(1, 2, 3, opt='hello')
args= (1, 2, 3) , opt= hello
>>>
You can hook access to class attributes (member variables), such as C # properties, accessors in Java beans, and so on.
When the Foo
class has an attribute called text
, you can declare properties using the property
function.
>>> class Foo:
... def __init__(self, text):
... self.__text = text
... def get_text(self):
... print('get_text')
... return self.__text
... def set_text(self, text):
... print('set_text')
... self.__text = text
... text = property(get_text, set_text)
...
>>> foo = Foo('foo')
>>> foo.text
get_text
'foo'
>>> foo.text = 'FOO'
set_text
>>> foo.text
get_text
'FOO'
>>>
By the way, if you add two underscores (__
) to the beginning of the name, you will not be able to access it with the same name.
It cannot be completely hidden like a private member of an access-controlled language, but it can convey the intent of not exposing it.
>>> foo.__text
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__text'
>>> foo._Foo__text
'FOO'
>>>
Properties can also be set in the decorator. This is ** a new style **.
Just a little about decorators. The decorator looks like C # attributes and Java annotations, but I think it's more like a macro or AOP. Please google for details.
>>> class Bar:
... def __init__(self, text):
... self.__text = text
... @property
... def text(self):
... print('property')
... return self.__text
... @text.setter
... def text(self, text):
... print('text.setter')
... self.__text = text
...
>>> bar = Bar('bar')
>>> bar.text
property
'bar'
>>> bar.text = 'BAR'
text.setter
>>> bar.text
property
'BAR'
>>>
Since Python is a dynamically typed language, both can be used in the same way as sequences in principle, except that lists are variable and tuples are immutable.
By the way, Python tuples can be written without parentheses except for empty tuples, but it is better to put parentheses to clearly indicate that they are tuples.
>>> t1 = (1, 2, 3)
>>> t2 = 1, 2, 3
>>> t1
(1, 2, 3)
>>> t2
(1, 2, 3)
>>> type(t1)
<class 'tuple'>
>>> type(t2)
<class 'tuple'>
>>>
Lists and tuples can be converted to each other using the list
and tuple
functions.
>>> a = [1, 2, 3]
>>> type(a)
<class 'list'>
>>> aa = tuple(a)
>>> aa
(1, 2, 3)
>>> type(aa)
<class 'tuple'>
>>> b = (4, 5, 6)
>>> type(b)
<class 'tuple'>
>>> bb = list(b)
>>> bb
[4, 5, 6]
>>> type(bb)
<class 'list'>
>>>
The so-called printf
style format seems to be old style.
However, old styles are not deprecated, it seems that old styles are just frozen in functionality, and new styles are more flexible to write.
Old styles are written as format string
%
value tuple
.
>>> 'x=%d, y=%d' % (10, 20)
'x=10, y=20'
>>>
The new style uses the string format
method.
This style can be used flexibly in various ways, such as changing the order of passing and passing a dictionary as an argument.
>>> dict = {'x': 10, 'y': 20, 'z': 30}
>>> 'z={z:d}, y={y:d}, x={x:d}'.format(**dict)
'z=30, y=20, x=10'
>>>
There is also a template string, but I didn't know how to use it.
>>> from string import Template
>>> s = Template('--- $foo --- $bar ---')
>>> s.substitute(foo='Foo', bar='Bar')
'--- Foo --- Bar ---'
>>> d = {'foo': 100, 'bar': 200}
>>> s.substitute(d)
'--- 100 --- 200 ---'
>>>
See the reference below for more information.
6.1.3.2. Format specification example (6.1. string — general string operations — Python 3.5.1 documentation) http://docs.python.jp/3/library/string.html#format-examples
6.1.4. Template strings (6.1. string — general string operations — Python 3.5.1 documentation) http://docs.python.jp/3/library/string.html#template-strings
How do I define methods like to_s
in Ruby, toString
in Java and JavaScript?
Python classes have special methods, __str__
and __repr__
, which you can implement to define a string representation of an object.
__str__
defines the string representation when converting to a string with the str
function or printing with the print
function.
__repr__
is unique to Python and defines a string representation on the interpreter. (Abbreviation for representation?)
>>> class Foo:
... def __init__(self, text):
... self.text = text
... def __str__(self):
... return self.text
... def __repr__(self):
... return '%s(\'%s\')' % (self.__class__.__name__, self.text)
...
>>> Foo('foo')
Foo('foo')
>>> print(Foo('foo'))
foo
>>> str(Foo('foo'))
'foo'
>>>
First, the result of the __repr__
method is output as a representation on the interpreter.
The second is the string representation of Foo ()
, that is, the result of the __str__
method is output by the print
function.
Third, the result of the __str__
method is also converted to a character string by the str
function and output as a representation on the interpreter.
You can use the repr
function to get the result of the __repr__
method as a string.
>>> s = repr(Foo())
>>> s
"Foo('foo')"
>>>
```
## Loan pattern (file open case)
Use the `with` statement.
You can do it with `try-finally`, but` with` is more concise.
8.5. with statement (8. compound statement — Python 3.5.1 documentation)
[http://docs.python.jp/3/reference/compound_stmts.html#with](http://docs.python.jp/3/reference/compound_stmts.html#with)
The following data
```
1,2,3
4,5,6
7,8,9
```
Assuming you have a text file called `data.txt` with, let's convert this to a list of numeric tuples.
```pycon
>>> with open('data.txt', 'r') as f:
... a = [tuple(map(int, line.split(','))) for line in f.read().split()]
...
>>> a
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
>>>
```
→ I was taught how to write these two lines more concisely. See the comments section.
Thank you, @shiracamus.
I've packed a lot, but I won't explain each one.
Notice the line of the `with` statement.
## I want to use a dictionary that maintains the registered order
If you need a dictionary that can iterate in the order you registered, like `LinkedHashMap` in Java
Use the `collections` module ʻOrderedDict` instead of the built-in dictionary.
```pycon
>>> from collections import OrderedDict
>>> d = dict([('y', 0), ('e', 0)])
>>> d
{'e': 0, 'y': 0}
>>> d['s'] = 0
>>> d
{'s': 0, 'e': 0, 'y': 0}
>>> for x in d:
... print(x)
...
s
e
y
>>> od = OrderedDict([('y', 0), ('e', 0)])
>>> od
OrderedDict([('y', 0), ('e', 0)])
>>> od['s'] = 0
>>> od
OrderedDict([('y', 0), ('e', 0), ('s', 0)])
>>> for x in od:
... print(x)
...
y
e
s
>>>
```
If you want to know about other collections, check out the documentation for the `collections` module.
8.3. collections — container data types — Python 3.5.1 documentation
[http://docs.python.jp/3/library/collections.html](http://docs.python.jp/3/library/collections.html)
## bonus
A little bit about Python ideas and rules.
PEP 8
There is a coding rule called PEP 8. You should follow this for the time being.
~~ (This is not a standard feature.) ~~
→ You pointed out that PEP 8 itself is a guideline (document), and it is strange to say that it is not a standard function.
`Pep8`, which checks the PEP 8 rules, and ʻautopep8`, which will be described later, need to be installed by` pip` etc., so these tools should have been written as "not standard features".
Thank you for pointing out, @ryunix.
Introduction — pep8-ja 1.0 documentation
[https://pep8-ja.readthedocs.io/ja/latest/](https://pep8-ja.readthedocs.io/ja/latest/)
Comply with Python coding standard PEP8 --Qiita
[http://qiita.com/ynakayama/items/8616f4c0c6e372de9a42](http://qiita.com/ynakayama/items/8616f4c0c6e372de9a42)
It can also be applied automatically with a tool called ʻautopep8`.
(As long as you don't do work that humans don't have to do.)
Postscript: The `pep8` command has been renamed to` pycodestyle`.
See the comments section for more information.
Thank you, @matobaa.
PEP 20
PEP 20 is something of a poetic form that expresses the idea of Python. Details are below.
Ideas about Python: PEP 20 --Life with Python
[http://www.lifewithpython.com/2013/01/pep-20-the-zen-of-python.html](http://www.lifewithpython.com/2013/01/pep-20-the-zen-of-python.html)
### What is PEP
PEP stands for Python Enhancement Proposal.
For details, refer to the "Development" section of Python on English Wikipedia.
Python (programming language) - Wikipedia, the free encyclopedia
#Development
[https://en.wikipedia.org/wiki/Python_(programming_language)#Development](https://en.wikipedia.org/wiki/Python_(programming_language)#Development)
### Compatibility with Python2
Python2 series and Python3 series are not compatible.
In my experience, which is still shallow, I felt that the handling of character strings has changed significantly.
Please note that there are quite a lot of sample code scattered on the Web that you do not know which is Python2 and which is Python3.
## in conclusion
Writing this article has become a great practice.
The features I've covered here are just the very basics of Python, so from now on I'd like to wrestle with many libraries, tools and frameworks and start using Python in earnest.
Until the end Thank you for reading.
## References
#1
Getting Started Python3 (O'REILLY)
#2
Python 3.5.1 documentation
[http://docs.python.jp/3/](http://docs.python.jp/3/)
Many others
Recommended Posts