顯示具有 [ Python 常見問題 ] 標籤的文章。 顯示所有文章
顯示具有 [ Python 常見問題 ] 標籤的文章。 顯示所有文章

2022年2月3日 星期四

[ Python 常見問題 ] How can I get the IP address from NIC in Python?

 Source from here

Question
So how can I get the IP address of specific network interface in Python?

HowTo

Method #1 (use external package)
You need to ask for the IP address that is bound to your eth0 interface. This is available from the netifaces package. Before all, let's check out network interfaces:
# ip addr show
...
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:9f:e6:d5 brd ff:ff:ff:ff:ff:ff
altname enp2s1
inet 192.168.37.131/24 brd 192.168.37.255 scope global dynamic noprefixroute ens33
valid_lft 1672sec preferred_lft 1672sec
inet6 fe80::6b54:4ab:9041:4fcd/64 scope link noprefixroute
valid_lft forever preferred_lft forever

Then check below code snippet for how to retrieve IP address:
>>> import netifaces as ni
>>> from pprint import pprint
>>> pprint(ni.ifaddresses('ens33'))
  1. {2: [{'addr''192.168.37.131',  
  2.       'broadcast''192.168.37.255',  
  3.       'netmask''255.255.255.0'}],  
  4. 10: [{'addr''fe80::6b54:4ab:9041:4fcd%ens33',  
  5.        'netmask''ffff:ffff:ffff:ffff::'}],  
  6. 17: [{'addr''00:0c:29:9f:e6:d5''broadcast''ff:ff:ff:ff:ff:ff'}]}  

>>> ni.ifaddresses('ens33')[ni.AF_INET][0]['addr']
'192.168.37.131'
>>> ni.interfaces()
['lo', 'ens33', 'br-85c9ddfa802f', 'docker0', 'br-1f95accf9779', 'br-227986c2fe47']

Method #2 (no external package)
Here's a way to get the IP address without using a python package:
>>> import socket
>>> import fcntl
>>> import struct
>>> socket.gethostbyname(socket.gethostname())
'127.0.1.1'
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> packed_iface = struct.pack('256s', 'ens33'.encode('utf_8'))
>>> packed_addr = fcntl.ioctl(sock.fileno(), 0x8915, packed_iface)[20:24]
>>> socket.inet_ntoa(packed_addr)
'192.168.37.131'


2022年1月26日 星期三

[ Python 常見問題 ] How to get symbolic link target in Python?

 Source From Here

Question
How do I extract the target path from a symbolic link?

HowTo
The problem with os.readlink() is it will only resolve 1 step of the link. We can have a situation where A links to another link B, and B link is dangling:
$ ln -s /tmp/example/notexist /tmp/example/B
$ ln -s /tmp/example/B /tmp/example/A
$ ls -l /tmp/example
A -> /tmp/example/B
B -> /tmp/example/notexist

Now in Python, os.readlink() gives you the first target:
>>> import os
>>> os.readlink('A')
'/tmp/example/B'

But in most situations I assume we are interested in the resolved path. So pathlib can help here:
>>> from pathlib import Path
>>> Path('A').resolve()
PosixPath('/tmp/example/notexist')

This message was edited 5 times. Last update was at 25/01/2022 20:27:24

2021年12月21日 星期二

[ Python 常見問題 ] How to use glob() to find files recursively?

 Source From Here

Question
This is what I have:
  1. glob(os.path.join('src','*.c'))  
but I want to search the subfolders of src. Something like this would work:
  1. glob(os.path.join('src','*.c'))  
  2. glob(os.path.join('src','*','*.c'))  
  3. glob(os.path.join('src','*','*','*.c'))  
  4. glob(os.path.join('src','*','*','*','*.c'))  
But this is obviously limited and clunky.

HowTo
Use pathlib.Path.rglob from the the pathlib module, which was introduced in Python 3.5.
  1. from pathlib import Path  
  2.   
  3. for path in Path('src').rglob('*.c'):  
  4.     print(path.name)  
If you don't want to use pathlib, use can use glob.glob('**/*.c'), but don't forget to pass in the recursive keyword parameter and it will use inordinate amount of time on large directories.

For cases where matching files beginning with a dot (.); like files in the current directory or hidden files on Unix based system, use the os.walk solution below. For older Python versions, use os.walk to recursively walk a directory and fnmatch.filter to match against a simple expression:
  1. import fnmatch  
  2. import os  
  3.   
  4. matches = []  
  5. for root, dirnames, filenames in os.walk('src'):  
  6.     for filename in fnmatch.filter(filenames, '*.c'):  
  7.         matches.append(os.path.join(root, filename))  


2021年9月17日 星期五

[ Python 常見問題 ] When using unittest.mock.patch, why is autospec not True by default?

 Source From Here

Question
When you patch a function using mock, you have the option to specify autospec as True:
If you set autospec=True then the mock with be created with a spec from the object being replaced. All attributes of the mock will also have the spec of the corresponding attribute of the object being replaced. Methods and functions being mocked will have their arguments checked and will raise a TypeError if they are called with the wrong signature.

(http://www.voidspace.org.uk/python/mock/patch.html)

I'm wondering why this isn't the default behavior? Surely we would almost always want to catch passing incorrect parameters to any function we patch?

HowTo
The only clear way to explain this, is to actually quote the documentation on the downside of using auto-speccing and why you should be careful when using it:
This isn’t without caveats and limitations however, which is why it is not the default behaviour. In order to know what attributes are available on the spec object, autospec has to introspect (access attributes) the spec. As you traverse attributes on the mock a corresponding traversal of the original object is happening under the hood. If any of your specced objects have properties or descriptors that can trigger code execution then you may not be able to use autospec. On the other hand it is much better to design your objects so that introspection is safe [4].

A more serious problem is that it is common for instance attributes to be created in the init method and not to exist on the class at all. autospec can’t know about any dynamically created attributes and restricts the api to visible attributes.

I think the key takeaway here is to note this line: autospec can’t know about any dynamically created attributes and restricts the api to visible attributes

So, to help being more explicit with an example of where autospeccing breaks, this example taken from the documentation shows this:
  1. >>> class Something:  
  2. ...   def __init__(self):  
  3. ...     self.a = 33  
  4. ...  
  5. >>> with patch('__main__.Something', autospec=True):  
  6. ...   thing = Something()  
  7. ...   thing.a  
  8. ...  
  9. Traceback (most recent call last):  
  10.   ...  
  11. AttributeError: Mock object has no attribute 'a'  
As you can see, auto-speccing has no idea that there is an attribute a being created when creating your Something object. There is nothing wrong with assigning a value to your instance attribute.

Observe the below functional example:
  1. import unittest  
  2. from mock import patch  
  3.   
  4. def some_external_thing():  
  5.     pass  
  6.   
  7. def something(x):  
  8.     return x  
  9.   
  10. class MyRealClass:  
  11.     def __init__(self):  
  12.         self.a = some_external_thing()  
  13.   
  14.     def test_thing(self):  
  15.         return something(self.a)  
  16.   
  17.   
  18.   
  19. class MyTest(unittest.TestCase):  
  20.     def setUp(self):  
  21.         self.my_obj = MyRealClass()  
  22.   
  23.     @patch('__main__.some_external_thing')      
  24.     @patch('__main__.something')  
  25.     def test_my_things(self, mock_something, mock_some_external_thing):  
  26.         mock_some_external_thing.return_value = "there be dragons"  
  27.         self.my_obj.a = mock_some_external_thing.return_value  
  28.         self.my_obj.test_thing()  
  29.   
  30.         mock_something.assert_called_once_with("there be dragons")  
  31.   
  32.   
  33. if __name__ == '__main__':  
  34.     unittest.main()  
So, I'm just saying for my test case I want to make sure that the some_external_thing() method does not affect the behaviour of my unittest, so I'm just assigning my instance attribute the mock per mock_some_external_thing.return_value = "there be dragons".

2021年9月3日 星期五

[ Python 常見問題 ] Why do Python classes inherit object?

 Source From Here

Question
Is there any reason for a class declaration to inherit from object? I just found some code that does this and I can't find a good reason why.
  1. class MyClass(object):  
  2.     # class code follows...  
Answer:
In Python 3, apart from compatibility between Python 2 and 3, no reason. In Python 2, many reasons.

Python 2.x story:
In Python 2.x (from 2.2 onwards) there's two styles of classes depending on the presence or absence of object as a base-class:

1. "classic" style classes: they don't have object as a base class:
  1. >>> class ClassicSpam:      # no base class  
  2. ...     pass  
  3. >>> ClassicSpam.__bases__  
  4. ()  
2. "new" style classes: they have, directly or indirectly (e.g inherit from a built-in type), object as a base class:
  1. >>> class NewSpam(object):           # directly inherit from object  
  2. ...    pass  
  3. >>> NewSpam.__bases__  
  4. (<type 'object'>,)  
  5. >>> class IntSpam(int):              # indirectly inherit from object...  
  6. ...    pass  
  7. >>> IntSpam.__bases__  
  8. (<type 'int'>,)   
  9. >>> IntSpam.__bases__[0].__bases__   # ... because int inherits from object    
  10. (<type 'object'>,)  
Without a doubt, when writing a class you'll always want to go for new-style classes. The perks of doing so are numerous, to list some of them:

Support for descriptors. Specifically, the following constructs are made possible with descriptors:
classmethod: A method that receives the class as an implicit argument instead of the instance.
staticmethod: A method that does not receive the implicit argument self as a first argument.
properties with property: Create functions for managing the getting, setting and deleting of an attribute.
more...

* The __new__ static method: lets you customize how new class instances are created.
Method resolution order (MRO): in what order the base classes of a class will be searched when trying to resolve which method to call.
* More

If you don't inherit from object, forget these. A more exhaustive description of the previous bullet points along with other perks of "new" style classes can be found here.

One of the downsides of new-style classes is that the class itself is more memory demanding. Unless you're creating many class objects, though, I doubt this would be an issue and it's a negative sinking in a sea of positives.

Python 3.x story:
In Python 3, things are simplified. Only new-style classes exist (referred to plainly as classes) so, the only difference in adding object is requiring you to type in 8 more characters. This:
  1. class ClassicSpam:  
  2.     pass  
is completely equivalent (apart from their name :-) to this:
  1. class NewSpam(object):  
  2.      pass  
and to this:
  1. class Spam():  
  2.     pass  
All have object in their __bases__.
  1. >>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]  
  2. [True, True, True]  
So, what should you do?
In Python 2: always inherit from object explicitly. Get the perks.

In Python 3: inherit from object if you are writing code that tries to be Python agnostic, that is, it needs to work both in Python 2 and in Python 3. Otherwise don't, it really makes no difference since Python inserts it for you behind the scenes.

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...