前言
- 搞科研,最重要的还是得看懂别人的源代码。
这就意味着python不能太差
看到比较有用的,或者不怎么看懂的代码,就搜索并学习,放在这里,供学习参考。 - 最重要的技能:
∗ ∗ 在编译器中对包或者类或者方法,点击 F 12 查看源码,而不是百度问怎么获得啥啥参数 ∗ ∗ \color{red}** 在编译器中对包或者类或者方法,点击F12查看源码,而不是百度问怎么获得啥啥参数** ∗∗在编译器中对包或者类或者方法,点击F12查看源码,而不是百度问怎么获得啥啥参数∗∗ - 可能会有错误,但都给出了程序的运行结果,可自行判断
∗ ∗ ( P y t h o n 3.9.18 ) ∗ ∗ \color{red}**(Python 3.9.18)** ∗∗(Python3.9.18)∗∗
魔方方法 __dict__, __setattr__ , __getattr__ , __getattribute__
- 类对象的属性会被放在
__dict__
中
class myClass():
def __init__(self):
print(self.__dict__)
self.name = "Alice"
print(self.__dict__)
print(type(self.__dict__))
c = myClass()
"""
{}
{'name': 'Alice'}
<class 'dict'>
"""
- 自然,每次设置属性和获取属性的时候,会调用对应的
__setattr__
和__getattribute__
/__getattr__
方法
那么后面两个有什么区别吗?-
如果属性存在,那么只进入
__getattribute__
,否则才会再进入__getattr__
- 注意:在
__getattribute__
中返回self.xxx
当然会递归报错,需要调用object.__getattribute()
即不能在__getattribute__
中写return self__dict__[xxx]
-
如果属性存在,那么只进入
from typing import Any
class myClass():
def __init__(self):
self.name = "Alice"
def __setattr__(self, __name: str, __value: Any) -> None:
print("Now set " + __name + " to " + __value)
self.__dict__[__name] = __value
def __getattribute__(self, __name: str) -> Any:
print("__getattribute__ : Now get " + __name)
return object.__getattribute__(self, __name)
def __getattr__(self, __name: str) -> Any:
print("__getattr__ : Now get " + __name)
if __name in self.__dict__:
return self.__dict__[__name]
else:
return "Not Exist"
c = myClass()
print("\n**********\n")
print(c.name)
print("\n**********\n")
print(c.name2)
"""
Now set name to Alice
__getattribute__ : Now get __dict__
**********
__getattribute__ : Now get name
Alice
**********
__getattribute__ : Now get name2
__getattr__ : Now get name2
__getattribute__ : Now get __dict__
Not Exist
"""
- 还有一个是
__delattr__(self, __name)
,在删除该属性的时候调用,不赘述了。
hasattr(obj, name)
- 判断对象是否有某个属性
如果对象有该属性返回 True,否则返回 False
这里不需要在类里面使用也可以
super()
- 在 python3 中,可以直接调用
super().xxx
调用直接继承父类的方法。 - 注意把下面代码中
CB
类的super().__init__()
注释掉之后CC
类调用super().__init__()
是没法进入到CA
类中去的,尽管CC
类是间接继承自CA
类。
from typing import Any
class CA():
def __init__(self):
print("In A")
self.name = "Alice"
class CB(CA):
def __init__(self):
print("In B")
super().__init__()
self.name = "Bob"
class CC(CB):
def __init__(self):
print("In C")
super().__init__()
self.name = "Cindy"
A = CA()
print("\n*****************\n")
B = CB()
print("\n*****************\n")
C = CC()
print("\n*****************\n")
print(A.name)
print(B.name)
print(C.name)
"""
In A
*****************
In B
In A
*****************
In C
In B
In A
*****************
Alice
Bob
Cindy
"""
- 如果你希望修改或者返回父类的属性,可以:
super().__setattr__(__name, __value)
super().__getattr__(__name)
注意:也可以直接 super().name
之类的,获得父类的属性。
但使用 super().__setattr__()
貌似更规范文章来源:https://www.toymoban.com/news/detail-779603.html
类型注解
- 随着项目越来越大,就越来越需要开发者对函数参数做类型的注解
知乎:python的类型注解【type hints】
里面很多例子都很好,建议看一看。
注意:只是作为注解,在运行中并不会限制参数类型!(有些编译器可能会有警告,大部分没有)
可以看到下面的例子,仍然运行成功了。
from typing import Any
def foo(x : str):
print("TYPE : " + str(type(x)))
print("VALUE : " + str(x))
foo({"123":456})
foo("123")
foo(123)
foo(["123"])
foo
"""
TYPE : <class 'dict'>
VALUE : {'123': 456}
TYPE : <class 'str'>
VALUE : 123
TYPE : <class 'int'>
VALUE : 123
TYPE : <class 'list'>
VALUE : ['123']
"""
- 所有的类型注解可以查看
typing
包 - 下面代码,
List是来源于typing.List, 而小写的list来源是class 'list'
def foo(x : list):
pass
from typing import List
def foo2(x : List):
pass
- 那么到底如何限定传入参数的类型呢?
比如module: Optional['Module']
,那么就写:
if not isinstance(module, Module) and module is not None:
raise TypeError(f"{torch.typename(module)} is not a Module subclass")
或者多用 assert
诊断也可以文章来源地址https://www.toymoban.com/news/detail-779603.html
解包 unpacking
- unpacking 是一种将序列(例如元组或列表)的元素分解为单独变量的操作。这可以通过在变量前使用 * 操作符(asterisk)来实现。
a = (1,2)
b, c = a
print(b,c)
a = (1,2)
(b, c) = a
print(b,c)
a = [1,2]
(b, c) = a
print(b,c)
a = [1,2,3,4,5]
b, *c = a
print(b,c)
"""
1 2
1 2
1 2
1 [2, 3, 4, 5]
"""
- 补充:
a,b,c = "123"
print(a,b,c)
a,b = 1,2
a,b = b,a
print(a,b)
a = 1,
print(a)
a, = [1]
print(a)
a, *b, c = [1,2,3,4,5]
print(a,b,c)
"""
1 2 3
2 1
(1,)
1
1 [2, 3, 4] 5
"""
zip() 函数
- 可以将多个序列 ‘压缩’ 成一个 zip 对象,用迭代器访问
迭代器的次数等于多个序列的长度最小值。 - 序列,当然可以传入列表,元组,字典
a = [1,2,3,4]
b = ['a','b','c',6 ,7]
for x,y in zip(a,b):
print(x,y)
print(list(zip(a,b)))
"""
1 a
2 b
3 c
4 6
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 6)]
"""
- 也可以利用这个来构建字典
a = [1,2,3,4]
b = ['a','b','c',6 ,7]
dc = dict(zip(a,b))
for x,y in dc.items():
print(x,y)
"""
1 a
2 b
3 c
4 6
"""
到了这里,关于【Python】科研代码学习:一的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!