python 起名软件目录结构正式–附怎么样通过环境变量导入别的目录模块

“项目目录结构”其实也是属于”可读性和可维护性”的规模。

Java内部类详解

目录组织情势

至于怎样组织三个较好的Python工程目录结构,已经有一部分拿走了共同的认识的目录结构。在Stackoverflow的以此题材上,能见到我们对Python目录结构的议论。

这边面说的已经很好了,小编也不打算重新造轮子列举各类不一样的情势,这其间小编说一下作者的知道和认知。

如果你的品种名称为foo, 笔者比较提议的最方便飞速目录结构那样就够用了:

Foo/
|-- bin/
|   |-- foo
|
|--conf/
|  |--__init__.py
|  |--settings.py
|
|-- foo/
|   |-- tests/
|   |   |-- __init__.py
|   |   |-- test_main.py
|   |
|   |-- __init__.py
|   |-- main.py
|
|-- docs/
|   |-- conf.py
|   |-- abc.rst
|
|-- setup.py
|-- requirements.txt
|-- README

大致解释一下:

  1. bin/:
    存放项目标局部可执行文件,当然你能够起名script/等等的也行。
  2. conf/:存放项目布局文件
  3. foo/: 存放项指标持有源代码。(一)
    源代码中的全体模块、包都应该置身此目录。不要置于顶层目录。(二)
    其子目录tests/寄存单元测试代码; (三)
    程序的输入最棒命名称为main.py
  4. docs/: 存放一些文书档案。
  5. setup.py: 安装、布置、打包的剧本。
  6. requirements.txt: 存放软件注重的表面Python包列表。
  7. README: 项目说明文件。

除了那么些之外,有局地方案提交了尤其多的始末。比如LICENSE.txt,ChangeLog.txt文本等,作者从没列在那里,因为这几个事物首要是体系开源的时候供给用到。倘使您想写贰个开源软件,目录该怎么组织,能够参见那篇小说

哪些运用差别目录下的文本

上述图目录结构为例,大家在main.py中,使用bin目录下文件,首先必要找到Foo/目录,然后才能导入Foo/下的子目录的模块,并且供给形成自动获取,不能够写死,那时候就选用到os模块

import os

import sys

一、找到文件的相对路径

os.path.abspath(__file__)    #获取文件的相对路径,包蕴文件名

二、获取文件的目录

os.path.dirname(os.path.abspath(__file__) )    #
 例如main.py的目录是foo/ 

三、再度取得文件目录的父目录

BASE_DIR =
os.path.dirname(os.path.dirname(os.path.abspath(__file__) ))

四、添加到环境变量中

sys.path.append(BASE_DIR)

5、导入须要的目录

①.  import bin

②. from bin import *

三种艺术导入,各有优缺点,后续会详细讲解,至此,就能够使用其余目录的模块,欢迎各位看官留言指导

 

  说到内部类这么些词,想必很多个人都不面生,可是又会觉得不熟悉。原因是日常编写制定代码时恐怕用到的景色不多,用得最多的是在有事件监听的景色下,并且即采纳到也很少去下结论内部类的用法。明日大家就来一探毕竟。上边是本文的目录大纲:

  一.内种类基础

  二.时刻思念驾驭其中类

  三.内项指标施用情形和利益

  4.广阔的与其间类相关的笔试面试题

  若有不正之处,请多担待并欢迎批评指正。

  请尊崇我劳动成果,转发请标明原来的书文链接:

  http://www.cnblogs.com/dolphin0520/p/3811445.html

一.内品种基础

  在Java中,能够将叁个类定义在另多个类里面也许二个方法里面,那样的类称为内部类。广泛意义上的中间类1般的话蕴含那各个:成员内部类、局部内部类、匿名内部类和静态内部类。上边就先来打听一下那多种内部类的用法。

  一.分子内部类

  成员内部类是最常见的内部类,它的概念为位于另2个类的当中,形如上面包车型客车花样:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Circle {
    double radius = 0;
     
    public Circle(double radius) {
        this.radius = radius;
    }
     
    class Draw {     //内部类
        public void drawSahpe() {
            System.out.println("drawshape");
        }
    }
}

  那样看起来,类Draw像是类Circle的1个分子,Circle称为外部类。成员内部类能够无偿访问外部类的具备成员属性和分子方法(包括private成员和静态成员)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Circle {
    private double radius = 0;
    public static int count =1;
    public Circle(double radius) {
        this.radius = radius;
    }
     
    class Draw {     //内部类
        public void drawSahpe() {
            System.out.println(radius);  //外部类的private成员
            System.out.println(count);   //外部类的静态成员
        }
    }
}

  可是要留心的是,当成员内部类具有和外部类同名的积极分子变量也许措施时,会产生隐藏现象,即暗许意况下访问的是成员内部类的分子。如若要访问外部类的同名成员,须要以下边包车型大巴款式展开走访:

1
2
外部类.this.成员变量
外部类.this.成员方法

  固然成员内部类可以无条件地走访外部类的成员,而外部类想访问成员内部类的分子却不是这么随便了。在外部类中1旦要访问成员内部类的成员,必须先创制三个分子内部类的指标,再通过指向那些目的的引用来访问:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Circle {
    private double radius = 0;
 
    public Circle(double radius) {
        this.radius = radius;
        getDrawInstance().drawSahpe();   //必须先创建成员内部类的对象,再进行访问
    }
     
    private Draw getDrawInstance() {
        return new Draw();
    }
     
    class Draw {     //内部类
        public void drawSahpe() {
            System.out.println(radius);  //外部类的private成员
        }
    }
}

  成员内部类是专属外部类而存在的,相当于说,假如要创制成员内部类的靶子,前提是必须存在三个表面类的对象。成立成员内部类对象的形似方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Test {
    public static void main(String[] args)  {
        //第一种方式:
        Outter outter = new Outter();
        Outter.Inner inner = outter.new Inner();  //必须通过Outter对象来创建
         
        //第二种方式:
        Outter.Inner inner1 = outter.getInnerInstance();
    }
}
 
class Outter {
    private Inner inner = null;
    public Outter() {
         
    }
     
    public Inner getInnerInstance() {
        if(inner == null)
            inner = new Inner();
        return inner;
    }
      
    class Inner {
        public Inner() {
             
        }
    }
}

  内部类能够具有private访问权限、protected访问权限、public访问权限及包访问权限。比如上边包车型客车例证,假诺成员内部类Inner用private修饰,则只幸好外部类的中间访问,假设用public修饰,则其余地点都能访问;如若用protected修饰,则只可以在同1个包下只怕接续外部类的情事下访问;假如是暗许访问权限,则只可以在同二个包下访问。那或多或少和外部类有几许不平等,外部类只好被public和包访问三种权限修饰。笔者个人是那般精晓的,由于成员内部类看起来像是外项目标多个分子,所以能够像类的成员平等具有各种权力修饰。

  2.局地内部类

  局地内部类是概念在多少个格局只怕八个效能域里面的类,它和分子内部类的界别在于有的内部类的走访仅限于方法内可能该成效域内。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class People{
    public People() {
         
    }
}
 
class Man{
    public Man(){
         
    }
     
    public People getWoman(){
        class Woman extends People{   //局部内部类
            int age =0;
        }
        return new Woman();
    }
}

  注意,局地内部类就像方法里面包车型大巴四个局地变量1样,是没办法有public、protected、private以及static修饰符的。

  3.匿名内部类

  匿名内部类应该是平日大家编辑代码时用得最多的,在编辑事件监听的代码时采纳匿名内部类不但便宜,而且使代码尤其不难有限协助。上面那段代码是一段Android轩然大波监听代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
scan_bt.setOnClickListener(new OnClickListener() {
             
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                 
            }
        });
         
        history_bt.setOnClickListener(new OnClickListener() {
             
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                 
            }
        });

  那段代码为八个按钮设置监听器,那里面就接纳了匿名内部类。这段代码中的:

1
2
3
4
5
6
7
8
new OnClickListener() {
             
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                 
            }
        }

  正是匿名内部类的运用。代码中须要给按钮设置监听器对象,使用匿名内部类能够在促成父类可能接口中的方法情状下同时发出三个相应的对象,但是前提是其一父类也许接口必须先存在才能这么使用。当然像上边那种写法也是能够的,跟下边运用匿名内部类达到效果同样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void setListener()
{
    scan_bt.setOnClickListener(new Listener1());       
    history_bt.setOnClickListener(new Listener2());
}
 
class Listener1 implements View.OnClickListener{
    @Override
    public void onClick(View v) {
    // TODO Auto-generated method stub
             
    }
}
 
class Listener2 implements View.OnClickListener{
    @Override
    public void onClick(View v) {
    // TODO Auto-generated method stub
             
    }
}

  那种写法即便能达到平等的成效,不过既冗长又麻烦维护,所以1般选用匿名内部类的点子来编排事件监听代码。同样的,匿名内部类也是无法有访问修饰符和static修饰符的。

  匿名内部类是唯1一种未有构造器的类。正因为其尚无构造器,所以匿名内部类的接纳限制万分有限,抢先5二%匿名内部类用于接口回调。匿名内部类在编写翻译的时候由系统自动起名字为Outter$1.class。1般的话,匿名内部类用于后续其他类恐怕达成接口,并不供给扩张额外的章程,只是对继续方法的兑现或是重写。

  肆.静态内部类

  静态内部类也是概念在另贰个类里面包车型地铁类,只可是在类的近来多了三个主要字static。静态内部类是不须要依靠于外部类的,这一点和类的静态成员属性有点类似,并且它无法利用外部类的非static成员变量可能措施,这一点很好精晓,因为在尚未外部类的目的的事态下,可以创设静态内部类的靶子,若是允许访问外部类的非static成员就会发生冲突,因为外表类的非static成员必须依附于现实的指标。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Test {
    public static void main(String[] args)  {
        Outter.Inner inner = new Outter.Inner();
    }
}
 
class Outter {
    public Outter() {
         
    }
     
    static class Inner {
        public Inner() {
             
        }
    }
}

  起名 1

2.尖锐通晓里面类

  壹.为什么成员内部类能够无偿访问外部类的积极分子?

  在此以前,我们早就商量过了成员内部类能够无偿访问外部类的积极分子,那现实究竟是何等促成的呢?上面通过反编写翻译字节码文件看看毕竟。事实上,编写翻译器在进展编写翻译的时候,会将成员内部类单独编写翻译成四个字节码文件,上边是Outter.java的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Outter {
    private Inner inner = null;
    public Outter() {
         
    }
     
    public Inner getInnerInstance() {
        if(inner == null)
            inner = new Inner();
        return inner;
    }
      
    protected class Inner {
        public Inner() {
             
        }
    }
}

  编写翻译之后,出现了三个字节码文件:

起名 2

  反编写翻译Outter$Inner.class文件得到下边消息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
E:\Workspace\Test\bin\com\cxh\test2>javap -v Outter$Inner
Compiled from "Outter.java"
public class com.cxh.test2.Outter$Inner extends java.lang.Object
  SourceFile: "Outter.java"
  InnerClass:
   #24= #1 of #22//Inner=class com/cxh/test2/Outter$Inner of class com/cxh/tes
t2/Outter
  minor version: 0
  major version: 50
  Constant pool:
const #1 class        #2;     //  com/cxh/test2/Outter$Inner
const #2 = Asciz        com/cxh/test2/Outter$Inner;
const #3 class        #4;     //  java/lang/Object
const #4 = Asciz        java/lang/Object;
const #5 = Asciz        this$0;
const #6 = Asciz        Lcom/cxh/test2/Outter;;
const #7 = Asciz        <init>;
const #8 = Asciz        (Lcom/cxh/test2/Outter;)V;
const #9 = Asciz        Code;
const #10 = Field       #1.#11//  com/cxh/test2/Outter$Inner.this$0:Lcom/cxh/t
est2/Outter;
const #11 = NameAndType #5:#6;//  this$0:Lcom/cxh/test2/Outter;
const #12 = Method      #3.#13//  java/lang/Object."<init>":()V
const #13 = NameAndType #7:#14;//  "<init>":()V
const #14 = Asciz       ()V;
const #15 = Asciz       LineNumberTable;
const #16 = Asciz       LocalVariableTable;
const #17 = Asciz       this;
const #18 = Asciz       Lcom/cxh/test2/Outter$Inner;;
const #19 = Asciz       SourceFile;
const #20 = Asciz       Outter.java;
const #21 = Asciz       InnerClasses;
const #22 class       #23;    //  com/cxh/test2/Outter
const #23 = Asciz       com/cxh/test2/Outter;
const #24 = Asciz       Inner;
 
{
final com.cxh.test2.Outter this$0;
 
public com.cxh.test2.Outter$Inner(com.cxh.test2.Outter);
  Code:
   Stack=2, Locals=2, Args_size=2
   0:   aload_0
   1:   aload_1
   2:   putfield        #10//Field this$0:Lcom/cxh/test2/Outter;
   5:   aload_0
   6:   invokespecial   #12//Method java/lang/Object."<init>":()V
   9:   return
  LineNumberTable:
   line 160
   line 189
 
  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      10      0    this       Lcom/cxh/test2/Outter$Inner;
 
 
}

  第贰壹行到35行是常量池的内容,上边逐1第18行的内容:

final com.cxh.test2.Outter this$0;

  那行是一个对准外部类对象的指针,看到那里或许大家茅塞顿开了。也便是说编写翻译器会默许为成员内部类添加了二个对准外部类对象的引用,那么这一个引用是什么赋初值的吧?下边接着看当中类的构造器:

public com.cxh.test2.Outter$Inner(com.cxh.test2.Outter);

  从那边能够观望,固然我们在概念的里边类的构造器是无参构造器,编写翻译器还是会私下认可添加一个参数,该参数的花色为指向外部类对象的三个引用,所以成员内部类中的Outter
this&0
指针便指向了表面类对象,由此能够在成员内部类中随机走访外部类的积极分子。从那里也直接表明了成员内部类是信赖于外部类的,借使未有开创外部类的指标,则不能够对Outter
this&0引用进行伊始化赋值,也就不可能创设成员内部类的对象了。

  2.为啥某个内部类和匿名内部类只可以访问1些final变量?

  想必那个问题也曾经干扰过无数人,在商量这些题材此前,先看下边那段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Test {
    public static void main(String[] args)  {
         
    }
     
    public void test(final int b) {
        final int a = 10;
        new Thread(){
            public void run() {
                System.out.println(a);
                System.out.println(b);
            };
        }.start();
    }
}

  那段代码会被编译成五个class文件:Test.class和Test1.class。暗许情状下,编写翻译器会为匿名内部类和1部分内部类起名称为Outterx.class(x为正整数)。

  起名 3

  依照上海教室能够,test方法中的匿名内部类的名字被起为 Test$壹。

  上段代码中,若是把变量a和b后面的任2个final去掉,那段代码都编写翻译可是。大家先思索这么2个难点:

  当test方法执行完成之后,变量a的生命周期就结束了,而那时Thread对象的生命周期很或然还未曾终止,那么在Thread的run方法中延续访问变量a就改成不或者了,可是又要落实如此的效益,怎么做呢?Java采纳了 复制 
的手腕来解决这些题目。将这段代码的字节码反编写翻译可以收获上面包车型大巴始末:

起名 4

  大家看看在run方法中有一条指令:

bipush 10

  那条指令表示将操作数10压栈,表示使用的是三个地点局地变量。那一个历程是在编写翻译时期由编写翻译器暗许实行,假使这一个变量的值在编写翻译时期能够规定,则编写翻译器暗许会在匿名内部类(局部内部类)的常量池中添加二个内容优良的字面量或直接将相应的字节码嵌入到实施字节码中。那样壹来,匿名内部类使用的变量是另2个片段变量,只不过值和措施中有个别变量的值优良,因而和艺术中的局地变量完全部独用立开。

  上边再看三个例证:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test {
    public static void main(String[] args)  {
         
    }
     
    public void test(final int a) {
        new Thread(){
            public void run() {
                System.out.println(a);
            };
        }.start();
    }
}

  反编写翻译获得:

起名 5

  大家看出匿名内部类Test$一的构造器含有多个参数,多少个是指向外部类对象的引用,一个是int型变量,很精通,那里是将变量test方法中的形参a以参数的款型传进来对匿名内部类中的拷贝(变量a的正片)进行赋值开首化。

  也就说只要某些变量的值在编写翻译时期就能够规定,则直接在匿名内部里面成立贰个正片。假若局地变量的值无法在编写翻译时期鲜明,则透过构造器传参的主意来对拷贝进行开首化赋值。

  从上面可以观察,在run方法中访问的变量a根本就不是test方法中的局地变量a。那样一来就消除了前方所说的
生命周期不雷同的难点。不过新的题材又来了,既然在run方法中走访的变量a和test方法中的变量a不是同多少个变量,当在run方法中改变变量a的值的话,会油不过生什么情状?

  对,会促成数据不1致性,那样就达不到原来的意向和需求。为了消除那几个标题,java编写翻译器就限制必须将变量a限制为final变量,不一样意对变量a举行转移(对于引用类型的变量,是不容许指向新的目的),那样数据不壹致性的难点就可以缓解了。

  到此处,想必大家应该通晓为何方法中的局地变量和形参都不能够不用final进行限定了。

  3.静态内部类有特异的地点呢?

  之前边能够知道,静态内部类是不借助于表面类的,也就说能够在不创设外部类对象的景色下开创内部类的对象。别的,静态内部类是不具有指向外部类对象的引用的,这一个读者能够团结尝试反编写翻译class文件看一下就知道了,是从未Outter
this&0引用的。

3.内部类的行使处境和利益

  为何在Java中必要中间类?计算一下关键有以下四点:

  一.各类内部类都能独立的后续二个接口的落到实处,所以无论外部类是或不是已经一连了某些(接口的)落成,对于内部类都未曾影响。内部类使得多一连的消除方案变得完全,

  二.有益于将存在必然逻辑关系的类组织在协同,又有啥不可对外边隐藏。

  3.有益编写事件驱动程序

  四.造福编写线程代码

  个人认为第3点是最关键的由来之一,内部类的留存使得Java的多继承机制变得特别健全。

④.宽广的与中间类相关的笔试面试题

 一.基于注释填写(1),(2),(叁)处的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Test{
    public static void main(String[] args){
           // 初始化Bean1
           (1)
           bean1.I++;
           // 初始化Bean2
           (2)
           bean2.J++;
           //初始化Bean3
           (3)
           bean3.k++;
    }
    class Bean1{
           public int I = 0;
    }
 
    static class Bean2{
           public int J = 0;
    }
}
 
class Bean{
    class Bean3{
           public int k = 0;
    }
}

  从眼下可见,对于成员内部类,必须首发生外部类的实例化对象,才能生出内部类的实例化对象。而静态内部类不用产生外部类的实例化对象即可爆发内部类的实例化对象。

  创立静态内部类对象的形似情势为:  外部类类名.内部类类名 xxx = new
外部类类名.内部类类名()

  成立成员内部类对象的貌似方式为:  外部类类名.内部类类名 xxx =
外部类对象名.new 内部类类名()

  因而,(一),(贰),(3)处的代码分别为:

起名 6

Test test = new Test();    

  Test.Bean1 bean1 = test.new Bean1();   

Test test = new Test();    

  Test.Bean1 bean1 = test.new Bean1();   

 

起名 7

Test.Bean2 b2 = new Test.Bean2();   

Test.Bean2 b2 = new Test.Bean2();    

 

Bean bean = new Bean(); 

Bean.Bean3 bean3 =  bean.new Bean3();  



Bean bean = new Bean();     

Bean.Bean3 bean3 =  bean.new Bean3();  

起名 8

Bean bean = new Bean();     

Bean.Bean3 bean3 =  bean.new Bean3();

Bean bean = new Bean();     

Bean.Bean3 bean3 =  bean.new Bean3();

Bean bean = new Bean(); Bean bean = new Bean(); 

Bean bean = new Bean();     

Bean.Bean3 bean3 =  bean.new Bean3();   

贰.上边这段代码的出口结果是哪些?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Test {
    public static void main(String[] args)  {
        Outter outter = new Outter();
        outter.new Inner().print();
    }
}
 
 
class Outter
{
    private int a = 1;
    class Inner {
        private int a = 2;
        public void print() {
            int a = 3;
            System.out.println("局部变量:" + a);
            System.out.println("内部类变量:" this.a);
            System.out.println("外部类变量:" + Outter.this.a);
        }
    }
}

起名 93 2 1

3
2
1

 

  最后补充某个文化:关于成员内部类的一连问题。壹般的话,内部类是很少用来作为后续用的。不过当用来继续的话,要留意两点:

  壹)成员内部类的引用格局必须为 Outter.Inner.

  二)构造器中必须有指向外部类对象的引用,并由此这些引用调用super()。那段代码摘自《Java编制程序思想》

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class WithInner {
    class Inner{
         
    }
}
class InheritInner extends WithInner.Inner {
      
    // InheritInner() 是不能通过编译的,一定要加上形参
    InheritInner(WithInner wi) {
        wi.super(); //必须有这句调用
    }
  
    public static void main(String[] args) {
        WithInner wi = new WithInner();
        InheritInner obj = new InheritInner(wi);
    }
}

 

 参考资料:

  《java编制程序思想》

  http://www.cnblogs.com/chenssy/p/3388487.html

  http://blog.csdn.net/zhangjg_blog/article/details/20000769

  http://blog.csdn.net/zhangjg_blog/article/details/19996629

  http://blog.csdn.net/zhaoqianjava/article/details/6849812

  http://www.cnblogs.com/nerxious/archive/2013/01/24/2875649.html

 

作者:海子

    

出处:http://www.cnblogs.com/dolphin0520/

    

本博客中未声明转载的篇章归小编海子和天涯论坛共有,欢迎转发,但未经小编同意必须保留此段注解,且在篇章页面显著地点给出原著连接,不然保留追究法律义务的义务。

 

分类: Java基础

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图