3/100
slots
Python是动态语言,我们可以随时为对象绑定新的属性和方法。但是如果我们想限制类型的对象所能绑定的属性,则需要用到__slots__
。
1 | class Person(object): |
特殊方法
- 静态方法使用
@staticmethod
修饰 - 类方法使用
@classmethod
来修饰, 类方法的第一个参数必须是cls
,表示当前类的对象
3/100
Python是动态语言,我们可以随时为对象绑定新的属性和方法。但是如果我们想限制类型的对象所能绑定的属性,则需要用到__slots__
。
1 | class Person(object): |
@staticmethod
修饰@classmethod
来修饰, 类方法的第一个参数必须是cls
,表示当前类的对象2/100
python使用关键字class
来定义类,在类名后的括号里写父类。
1 | class Student(object): |
可见性
python并没有复杂而严格的可见性设置,虽然可以通过在方法和变量前加两个下划线来设置私有性,但这其实只是改变了访问规则而已。
1 | class Test: |
一般使用单下划线来表明方法或变量是受保护的,但这也只是一种隐含的意思而已。
@property
装饰器
可以使用@property来包装属性,这样属性将会被封装起来,使用@property装饰的方法可以作为getter来使用,想要使用setter则需要@xxx.setter来修饰。
1 | class Person(object): |
1/100
变量名使用_连接
my_var_name
_name_
单下划线开头为受保护的实例属性__name__
双下划线开头的为私有属性
使用 type()
来确认类型,使用下面的方法来转换类型:
1 | int() #转换成整数 |
除了常见的运算符外,python常用的还有:
1 | is |
python的if分支跟函数,类一样都是使用缩进来表示代码的层次结构。
1 | if name == 'a': |
for-in
python一般使用for name in collection
的方式来写循环语句
1 | sum = 0 |
定义函数的关键字是 def
1 | def foo(a): |
python中函数的参数可以设置默认值,所以使用的时候可以忽略部分参数或者直接指定某些参数,所以python的函数不需要像Java一样重载
1 | def add(a=0, b=0, c=0): |
还可以定义可变参数来接收无法确定个数的参数:
1 | def add(*args): |
python一个文件就算一个模块,通过import
来导入指定模块的内容。
1 | # module1.py |
1 | # module2.py |
1 | # test |
还可以直接从模块导入具体的函数
1 | from module1 import foo |
模块中如果需要写入可执行语句,一般需要包装在 __name__ == '__main__'
中,这样除非直接运行该模块,这些可执行语句是不会被执行的
1 | def foo(): |
__name__
是python的一个隐藏属性:模块名。 被python解释器直接执行的模块名字叫 __main__
ER图笔记(一)
ER图 Entity Relationship Diagram
在线的端点通过下列符号来指定数量关系
1 | -- 1 |
1 | A-l-a |
1 | --{ multi |
1 | D-{d |
在线的中央插入下列关键字来指定方向
1 | up, u |
1 | A-u->Up |
1 | C-l->Left |
可以使用自带的模版来定义每个包
1 | package foo1 <<Node>> { |
1 | package foo1 <<Node>> { |
首先给出以下Enum:
1 | enum Size{ |
问下面的代码执行的结果是:
1 | public static void main(String[] args) { |
Size.SMALL
SMALL
Size@3cb5cdba
选项1是错的,局部变量可以使用final来修饰,从Java 10
开始,可以使用关键字var
来声明局部变量,声明的变量类型由初始化的类型决定。
选项2也是错的,switch-case从来都不需要面对所有情况写case。
选项3也是错的,当switch的判断条件是enum类型时,case里不需要写类名。
选项4是对的,enum类型默认重写了toString
方法,输出name的值。
选项5是错的,上面说了,enum的toString输出的是name,而不是HashCode.
最近针对一个Issue,需要给excel文件的读写功能增加CSV的支持,本来以为使用类似的方法可以直接写到DTO里面,结果一查,Java好像对CSV的支持还是最原始最基本的写法(并非贬义,可能是容易了反而不需要什么工具来读写CSV)。
总结成一句话就是,读写CSV就相当于读写一个纯字符串文件。
读取CSV文件大致分为以下几步:
FileInputStream
读取csv文件BufferedReader
来对输入流进行更高效的处理split(",")
分割1 | // 字符编码 设置下没坏处 |
跟上面读取CSV的操作正好反过来,写CSV文件分为以下几步:
FileOutputStream
输出文件BufferedWriter.write()
的话记得换行1 | // 文件路径和文件名 |
这都是啥啥啥
CLOB 是可变长度的字符(char)大(long)对象(Object),用于基于字符的数据,以字节Byte或者标准八字节OCTET为单位,最大长度是2G(2,147,483,647)
BLOB 是可变长度的二进制(Binary)大(long)对象(Object),用于保存语音,混合媒体等非传统数据,以字节Byte为单位,最大长度也是2G(2,147,483,647)
我们都知道计算机中一个0/1表示一个比特bit,八个比特表示一个字节byte。但是在实际应用中,byte可以表示4-10比特的不同长度,为了统一标准,将严格意义上的8bits也称为OCTET
类就是Class
Car
,之后就可以在任何地方反复调用这个蓝图来生产Car
的实体run()
和stop()
,为了确定让哪辆车启动哪辆车停下,我们需要把对象的车多为参数传递进方法,是不是有一种拿遥控器开车还要每次都设置开的哪辆车的感觉? 当我们需要在不同的地方使用这两个方法时,就要重新写一遍。如果我们把run()
和stop()
写到类Car
里面,就可以通过每个Car
的实体,直接调用启动和停止的方法,方法属于车的实体,不同实体间的启动停止互不影响,这就有开车那味儿了。Car
定义一个静态变量轮子数 = 4
,这样我们生成的每个车都可以使用这个变量,甚至不生成实例的时候,也可以使用Car.轮子数
, 只要看一下蓝图,就知道这个变量值。相比之下,实例变量就是指从属于实例的变量,比如排气量 长度 宽度
,如果要调用这些变量,直接通过Car.排气量
是不行的,因为图纸上可没具体写这变量是多少,需要先生成一个实体my_car = Car()
,然后给my_car
设置并使用Python中定义类使用的是关键字class
,类的范围通过统一的缩进来管理
1 | class Car: |
类的内部使用关键字def
来定义方法,方法必须至少有一个参数self
,self
的含义相当于Java的this
,指的是类的实例,可以通过self
来访问实例变量和方法。
__init__
是构造体,当我们使用类名来生成实例的时候,会根据参数来调用对应的构造体生成实例,最基本的写法就是直接通过构造体给实例变量初始化,比如使用上面代码里得构造体:Car(54321)
。
Python中使用__
双下划线来定义私有变量和私有方法,私有的元素无法在外部通过实例名或者类名访问到
就像Java中所有的类都是Object的字类,都继承了一些基本的方法一样,Python中也有一些类的专有方法, 且可以重写:
跟同事聊了聊为什么要使用类,想起了一个很重要的点:内存管理。
如果我们不适用类来管理方法和变量的话,程序运行过程中,定义的变量和方法就会一直存在,占用内存空间;但是当我们使用了类之后,则可以在需要的时候声明类的实例来调用内存,当一个实例不再被使用的时候,又可以通过垃圾回收自动收回内存(垃圾回收机制不同语言有不同的做法)。这样我们的程序才可以根据需求灵活地使用资源。
当然,方法和变量的管理更方便什么的,也算使用类的好处
git prune
简单地说就是一个清扫(housekeeping)的命令。
使用git查看分支,可以看到分支有三个重要分类:本地分支,本地-远程分支的参照,远程分支
比如我们在github上merge了一个PR,顺手删除了一个分支,这时在本地的电脑上本删除的分支对应的本地分支,远程分支,远程本地的参照关系都还存在,如果我们使用git branch -D name
删除该分支, 会发现只删除了本地的分支,所参照的远程分支origin/name
依然存在,清理这种残留垃圾的命令的时候,就是用到了prune。
git remove prune
和 git fetch --prune
git remove prune
清理所有已经删掉的远程分支参照,但是不会删除本地分支
git fetch --prune
则是清理完远程的无用分支之后,再把最近状态fetch到本地