特种性质和措施分析,Android日志打字与印刷工具

方法一(列表解析式):

__dict__

  • Python 中,壹切皆对象
  • 不管是类依然实例的习性和方法,都契合 object.attribute
    格式。并且属性类型

class A(object):
    pass
a = A()
dir(a)

输出:

    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__','__eq__','__format__','__ge__','__getattribute__','__gt__','__hash__','__init__','__init_subclass__','__le__','__lt__', '__module__','__ne__','__new__', '__reduce__', '__reduce_ex__','__repr__','__setattr__', '__sizeof__', '__str__', '__subclasshook__','__weakref__']

class Spring(object):
    season = 'the spring of class'
Spring.__dict__

输出:

    mappingproxy({'__dict__': <attribute '__dict__' of 'Spring' objects>,
                  '__doc__': None,
                  '__module__': '__main__',
                  '__weakref__': <attribute '__weakref__' of 'Spring' objects>,
                  'season': 'the spring of class'})

#访问的是类属性
print(Spring.__dict__['season'])
print(Spring.season)

输出:

 'the spring of class'

#访问的是实例属性,因为class中没有定义实例属性所以打印为空
s = Spring()
s.__dict__

输出:

 {}

s.season    #访问的类属性

输出:

 'the spring of class'

#为class 的实例 中添加一个 season 属性
s.season = "instance";
s.__dict__

输出:

{'season': 'instance'}

#当类属性和实例属性重名时,实例属性会覆盖掉类属性
s.__dict__['season']

输出:

'instance'

#但是类属性不会变
Spring.__dict__['season']

输出:

'the spring of class'

Spring.season

输出:

 'the spring of class'

#删除实例属性后,就回到了实例化类的时候的状态,没有实例属性,只有类属性
del s.season
s.__dict__

输出:

    {}

s.season  #类属性

输出:

    'the spring of class'

#属性和方法是同样的
class Spring_def(object):
    def tree(self,x):
        self.x= x
        return self.x

Spring_def.__dict__

输出:

 mappingproxy({'__dict__': <attribute '__dict__' of 'Spring_def' objects>,
                  '__doc__': None,
                  '__module__': '__main__',
                  '__weakref__': <attribute '__weakref__' of 'Spring_def' objects>,
                  'tree': <function __main__.Spring_def.tree>})

Spring_def.__dict__['tree']

输出:

    <function __main__.Spring_def.tree>

t = Spring_def()
t.__dict__

输出:

    {}

t.tree('value')
t.__dict__

输出:

    {}

class Spring_no(object):
    def tree(self,x):
        return x

ts = Spring_no()
ts.tree('No arg')
ts.__dict__

输出:

    {}

Spring_no.__dict__

输出:

    mappingproxy({'__dict__': <attribute '__dict__' of 'Spring_no' objects>,
                  '__doc__': None,
                  '__module__': '__main__',
                  '__weakref__': <attribute '__weakref__' of 'Spring_no' objects>,
                  'tree': <function __main__.Spring_no.tree>})

  刚上学Java时首先个接触的method就是System.out.println()
方法。不过近年来在应用它输出1些变量时出现了自家不领会的气象,首先上代码:

android-ueueo-log

澳门葡京备用网址 ,android-ueueo-log是Android日志输出工具,对输出的日记音信实行了美化,能够出口Json字符串,Xml字符串和简易的Java对象,并对输出消息进行了格式化。

感谢Logger,因为是基于Logger接下来依据自身的要求做的壹对修改。

list1 = ["abc","efg","hij"]
list2 = [i[0] for i in list1]
print list2

__slots__

  • 可见范围属性的定义
  • 优化内部存款和储蓄器使用
  • __dict__替换成__slots__
  • 用类给一天性质赋值后,实例就无法给那么些天性赋值了。
  • 也不能够增加产量实例属性,那样就把质量管理控制了起来。内部存款和储蓄器获得优化
  • 汪洋实例的话会显现出效果

class Spring_s(object):
    __slots__ = ("tree","flows")
dir(Spring_s)

输出:

    ['__class__','__delattr__','__dir__','__doc__','__eq__', '__format__','__ge__','__getattribute__', '__gt__','__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__','__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',  '__slots__', '__str__',   '__subclasshook__', 'flows',  'tree']

Spring_s.__dict__

输出:

mappingproxy({'__doc__': None,
                  '__module__': '__main__',
                  '__slots__': ('tree', 'flows'),
                  'flows': <member 'flows' of 'Spring_s' objects>,
                  'tree': <member 'tree' of 'Spring_s' objects>})

Spring_s.__slots__

输出:

    ('tree', 'flows')

ts = Spring_s()
ts.__slots__

输出:

    ('tree', 'flows')

#使用__slots__后就没有__dict__ 属性了
ts.__dict__

输出:

#错误
    ---------------------------------------------------------------------------

    AttributeError                            Traceback (most recent call last)

    <ipython-input-40-f3db88226dd5> in <module>()
          1 #使用__slots__后就没有__dict__ 属性了
    ----> 2 ts.__dict__


    AttributeError: 'Spring_s' object has no attribute '__dict__'

Spring_s.tree = "liushu"
Spring_s.tree

输出:

    'liushu'

# 报错中显示 实例属性 tree 只是制度的,不能修改
ts.tree = "yangshu"

输出:

#错误
    ---------------------------------------------------------------------------

    AttributeError                            Traceback (most recent call last)

    <ipython-input-42-d6b9cb191c20> in <module>()
          1 # 报错中显示 实例属性 tree 只是制度的,不能修改
    ----> 2 ts.tree = "yangshu"


    AttributeError: 'Spring_s' object attribute 'tree' is read-only

ts.tree

输出:

    'liushu'

  • 前方早已由此类给属性赋值了,就不能够用实例属性来修改。
  • 当使用实例给属性赋值后,还是能再用实例来给属性赋值,但是当以此天性被类赋值后,就不能够再用实例给属性赋值了,只好用类来给属性赋值.

#第一次实例赋值
ts.flows = "meigui"
ts.flows

输出:

    'meigui'

#第二次实例赋值
ts.flows = "yueji"
ts.flows

输出:

    'yueji'

#使用类赋值
Spring_s.flows = "shuixianhua"
Spring_s.flows

输出:

 'shuixianhua'

#实例的属性的值会变成类属性的值
ts.flows

输出:

    'shuixianhua'

#再用实例给属性赋值就会报只读错误
ts.flows = "qianniuhua"

输出:

#错误
    ---------------------------------------------------------------------------

    AttributeError                            Traceback (most recent call last)

    <ipython-input-48-726c06affe50> in <module>()
          1 #再用实例给属性赋值就会报只读错误
    ----> 2 ts.flows = "qianniuhua"


    AttributeError: 'Spring_s' object attribute 'flows' is read-only

Spring_s.flows = "baihe"
Spring_s.flows

输出:

    'baihe'

ts.flows

输出:

    'baihe'

  • 实例中添加属性

# 新增实例失败 
ts.water = "green"

输出:

#错误
    ---------------------------------------------------------------------------

    AttributeError                            Traceback (most recent call last)

    <ipython-input-52-cde7efd2f5b8> in <module>()
    ----> 1 ts.water = "green"


    AttributeError: 'Spring_s' object has no attribute 'water'

  

特性

  • 出口Json,Xml和Java对象(包涵数组,集合,Map),并展开了格式化缩进;
  • 输出打字与印刷日志的格局调用栈消息;
  • 出口当前线程音讯;
  • 支撑将日志存储到文件中;
  • 特种性质和措施分析,Android日志打字与印刷工具。可随意支配日志输出级别;
  • 支撑日志的拼接组合输出;

澳门葡京备用网址 1

  

__getattr____setattr__ 和此外类似形式

  • __setattr__(self,name,value): 如若要给name赋值,就调用这些办法
  • __getattr__(self,name): 即使name被访问,同事它不设有,此办法被调用
  • __getattribute__(self,name):
    当name被访问时自动被调用(注意:那一个仅能用来新式类),无论name是还是不是留存,都要被调用
  • __delattr__(self,name): 假使要删减name,那个主意就被调用。

class B(object):
    pass
b = B()
b.x 

输出:

    ---------------------------------------------------------------------------

    AttributeError                            Traceback (most recent call last)

    <ipython-input-42-f8f5c58b62c7> in <module>()
          2     pass
          3 a = A()
    ----> 4 a.x


    AttributeError: 'A' object has no attribute 'x'

x 不是势力的成员(属性和方法)所以报错。相当于说,要是访问 b.x
,它不存在,那么快要转向到有个别操作 ,大家把这种状态叫做“拦截”。

class C(object):
    def __getattr__(self,name):
        print('you use getattr')
    def __setattr__(self,name,value):
        print('you use setattr')
        self.__dict__[name] = value

类C是新式类,出来一个措施,未有别的属性

c = C()
c.x

输出:

    you use getattr

理所当然根据开头class B 是要报错的。可是由于此地运用了
__getattr__(self,name) 当发现x不存在与目的__dict__
时,就会调用__getattr“拦截成员” 。

c.x = 7

输出:

    you use setattr

给目的的属性赋值是,调用了__setattr__(self,name,value)主意,那些主意有一句
self.__dict__[name] = value透过这一个讲话,就将品质和多太史存到了对象的
__dict__中。假使再调用这几个天性:

c.x  # x 已经存在于对象的 __dict__中

输出:

    7

使用__getattribute__(self,name):,只要访问属性就会调用它

class getAt(object):
    def __getattribute__(self,name):
        print('使用了getattribute')
        return object.__getattribute__(self,name)

at = getAt()
at.y

输出:

    使用了getattribute



    ---------------------------------------------------------------------------

    AttributeError                            Traceback (most recent call last)

    <ipython-input-54-6e81b53b32de> in <module>()
          1 at = getAt()
    ----> 2 at.y


    <ipython-input-53-a6779a4b213a> in __getattribute__(self, name)
          2     def __getattribute__(self,name):
          3         print('使用了getattribute')
    ----> 4         return object.__getattribute__(self,name)


    AttributeError: 'getAt' object has no attribute 'y'

  • 访问二个不设有的习性,即便拦截了但要么报错了。
  • 可是只要赋值后就足以访问了,因为如此就意味着做性子格已经存在于__dict__中了。即便依然被堵住,可是会把结果回到。

at.y = 9
at.y

输出:

    使用了getattribute
    9

留意:那里没有
return self.__dict__[name],因为只要用这么的点子访问self.__dict__假使访问那几个措施,就会去调用__getattribute__,那样就会极其递归下去,造成死循环。

 1 /*
 2 *
 3 * using method System.out.println/print
 4 *
 5 *
 6 */
 7 class Student{
 8 
 9     String name ;
10     Student(String name){
11         this.name = name ;
12     }
13     void show (){
14         System.out.println("name is :" + name );
15     }
16 
17 }
18 public class TestOutString {
19 
20 public static void main(String[] args){
21     int varInt = 1 ;
22     char varChar = 'h';
23     String varString = "hello world !";
24     int[] intArray = {1,2,3};
25     char[] charArray = {'1','2','3','4'};
26     Student studentObject = new Student("first");
27     Student[] studentArray = {new Student("1"),new Student("2"),new Student("3")};
28     String[] stringArray = {"1","2","3","4"};
29     boolean[] booleanArray = {true , false , true , false};
30     
31     
32     System.out.println(varInt);
33     System.out.println(varChar);
34     System.out.println(varString);
35     System.out.println(intArray);
36     System.out.println(charArray);
37     System.out.println(studentObject);
38     System.out.println(studentArray);
39     System.out.println(stringArray);
40     
41     /*
42     Result :
43     
44             1
45             h
46             hello world !
47             [I@54477b4e
48             1234
49             Student@20f0691c
50             [LStudent;@784be29
51             [Ljava.lang.String;@1be0799a
52             
53     Question : 
54     
55     we will get different value by using method--'System.out.println/print' 
56     
57     to output some variables with different type
58     
59     */

下载和导入

能够从Github上下载源码:android-ueueo-log

简书地址:http://www.jianshu.com/p/5719e25d970b

品类中选择Gradle导入:

dependencies {
   compile 'com.ueueo:ueueo-log:2.5'
}

措施二(普通写法):

示例:
''' study __getattr__  and  __setattr__'''
class Rectangle(object):
    ''' the width  and length of Rectangle'''
    def __init__(self):
        self.width = 0
        self.height = 0
    def setSize(self,size):
        self.width,self.height = size
    def getSize(self):
        return self.width,self.height
if __name__ == "__main__":
    r = Rectangle()
    r.width = 3
    r.height = 4
    print (r.getSize())
    r.setSize((30,40))
    print(r.width)
    print(r.height)

输出:

    (3, 4)
    30
    40

长度宽度赋值的时候必须是二个元组,里面包蕴长度宽度。革新。。。

class Rectangle_2(object):
    ''' 使用property改进调用方法传参'''
    def __init__(self):
        self.width = 0
        self.height = 0
    def setSize(self,size):
        self.width,self.height = size
    def getSize(self):
        return self.width,self.height
    #---------新加---------#
    size = property(getSize,setSize)
    #---------结束---------#
if __name__ == "__main__":
    r = Rectangle_2()
    r.width = 3
    r.length = 4
    print(r.size)
    r.size = 30, 40
    print (r.width)
    print (r.length)

输出:

    (3, 0)
    30
    4

尽管如此艺术调用仿佛属性壹样,然则未有用上特殊措施。继续革新。。。

class Rectangle_3(object):
    '''使用特殊方法'''
    def __init__(self):
        self.width = 0
        self.height = 0
    def __setattr__(self, name, value):
        if name == "size":
            self.width, self.height = value
        else:
            self.__dict__[name] = value
    def __getattr__(self, name):
        if name == "size":
            return self.width,self.height
        else:
            return AttributeError

if __name__ == "__main__":
    nr = Rectangle_3()
    nr.width = 3
    nr.height = 4
    print(nr.size)
    nr.size = 30,40
    print(nr.width)
    print(nr.height)

输出:

    (3, 4)
    30
    40

澳门葡京备用网址 2

怎样利用

list1 = ["abc","efg","hij"]
list2 = []
for i in range(len(list1)):
    list2.append(list1[i][0])
print list2

得到属性顺序

  • 经过实例获取其属性,如果在__dict__中有,就径直回到其结果,若是未有,就会到类属性中找。

class search(object):
    author = 'Python'
    def __getattr__(self , name):
        if name != 'author':
            return '查询的不是author属性'
if __name__ == '__main__':
    a = search()
    print(a.author)
    print(a.none)
    print(a.__dict__)

输出:

    Python
    查询的不是author属性
    {}

  • 伊始化后 a
    未有创立任何实例属性。实例属性__dict__是空,未有属性值,a.author
    则有值,因为是类属性,而实例中又从不,所以就去类属性中去找,所以就赶回了'Python'
  • 当a.none
    的时候不仅实例中并未有,类中也未有,所以就调用了__getattr__艺术。假设不写__getattr__方法就会报错了。
  • 这就是 通过实例查找个性的逐1

参照:《跟着老齐学Python:从入门到精通》 小编:齐伟 电子工业出版社

由上先后能够观望:

初始化

UELog共提供了6个早先化方法:

UELog.init("AAA");
UELog.init("AAA", 2);
UELog.init("AAA", 3, UELogLevel.INFO);
UELog.init("AAA", 4, UELogLevel.INFO, true);

率先个参数:全局日志打字与印刷的Tag(默许为UEUEO);
第二个参数:打印格局调用栈的数目(暗中认可为 1);
其八个参数:钦定日志打字与印刷级别,唯有要出口的日记级别大于等于(>=)此参数值,才会打字与印刷。
日志级别从低到高分别为:
VEKoleosSONOS=壹,DEBUG=二,INFO=三,WAXC60N=四,EPRADORO福特Explorer=5,ASSE冠道T=陆,NONE=七,当钦点为NONE时就不会输出任何日志了;
第七个参数:钦命日志是不是保存到文件中(暗中认可为false不保存)。
日记文件存款和储蓄路径为外部存款和储蓄空间的根目录下
UEUEO文件夹里,日志文件会基于不一样的Tag而存款和储蓄在差异的文书夹中,当程序运营打字与印刷第三条日志时会依照当前岁月创造日志文件,并且此次运维都存款和储蓄在此日志文件中,当退出应用重新开动进度,则会成立新的日记文件。

借使不实行任何起首化操作,则具有参数都为暗许值。

  

  使用System.out.println()输出骨干数据类型和char数组时正常,不过在输出int、string、object、object数组、Boolean数组时现身只输出接近
  ‘类名 @ 壹串十陆进制的数’  的字符串。发现原因有以下几点:

输出Json,Xml和Java对象

//输出Json字符串
UELog.json("{\"id\":221,\"name\":\"my name is ueueo\",\"desc\":\"this is description!\"}");
//输出Xml字符串
UELog.xml("<?xml version=\"1.0\" encoding=\"UTF-8\"?><html><title>this is a title</title><body>这个是网页</body></html>");

//创建Java对象
User user = new User();
user.id = 102;
user.name = "UEUEO";
user.age = 22;
//输出对象
UELog.object(user);   

出口结果个别如下图:

澳门葡京备用网址 3

输出:

  一.
System.out.println()(是PrintStream类的成员方法)方法只提供了以下几种数据类型输出的重载函数:

出口打印日志的主意调用栈新闻

澳门葡京备用网址 4

上海教室分别为出口一级方法调用栈,输入3级方法调用栈和不出口方法调用栈的日志输出结果。

前两条日志当有点子调用栈输出时,日志新闻会通过边框美化输出,而第三条日志因为不须要输出方法调用栈消息,而且日志音信是单行日志,输出时为了不占用控制台出口空间,所以不会添加边框。然而1旦出口多行日志则会有边框,例如:

UELog.i("第一行日志 \n 换行输出日志");

出口结果如下:

澳门葡京备用网址 5

['a', 'e', 'h']
['a', 'e', 'h']

  澳门葡京备用网址 6

Exception输出

try {
    Object obj = null;
    obj.toString();
} catch (Exception e) {
    UELog.e(e, "空指针异常");
}

出口结果如下:

澳门葡京备用网址 7

  

  所以大家在出口  boolean 、 char 、char【】 、 double 、float 、int
、 long
数据时会输出其对应的值。对于object的出口System.out.println方法会首先调用其     toString方法,然后将该对象的toString方法的再次回到值输出。关于toString方法的现实输出会在下边说明。

输出有骚动参数的字符串日志

     UELog.i("指定参数的日志输出  参数1:%d  参数2:%s   参数3:%s", 110, "apple", "ueueo");

输出结果如下:

澳门葡京备用网址 8

主意一和措施二出口相同,是等价的

  1. 由于System.out.println没有对int[] 、String[] 、 object[]
    数组输出的重载函数,所以在应用该措施输出这个数据类型时,该方法会将里面的参数作数组首成分来对待。也就  是说,System.out.println(intArray)
    等价于  
    System.out.println(intArray[0])。然后调用数组首成分的toString方法,并将其出口。

设置当前要打字与印刷日志的Tag,方法调用栈数量和文书存款和储蓄

上边表达了,当调用UELoginit艺术举办初叶化时,能够钦赐日志的Tag等配置新闻,那些计划影响的是全局的日志输出,可是有些时候大家可能希望最近要出口的日记与init艺术钦定的配备不平等,例如:

init时钦命Tag为AAA,但是当前的日记希望Tag为BBB,则:

UELog.init("AAA");            
UELog.i("输出的日志Tag是AAA");
UELog.tag("BBB").i("输出的日志Tag是AAA");
UELog.i("再次输出的日志Tag是AAA");

出口结果如下:

澳门葡京备用网址 9

除了这些之外能够独自钦赐Tag外,还足以钦定方法调用栈展现数量和是不是存款和储蓄到文件:

UELog.tag("BBB").method(3).file(true).i("输出的日志Tag是BBB,显示方法数量为3,并且保存到文件中");

  toString()方法:

日记的拼凑组合输出

为了便利我们知道自个儿所说的日记的拼接组合,俺先来举个例子:

当发送网络请求时,必要打印请求的U帕杰罗L、请求参数和再次来到结果,一般的做法是:

//打印请求地址
UELog.i("POST  http://www.baidu.com/api/gps");
//打印请求参数
UELog.json("{\"id\":221}");
//打印返回结果
UELog.json("{\"name\":\"my name is ueueo\",\"desc\":\"this is description!\"}");

也正是分步打字与印刷数据,那样打字与印刷出来的结果如下:

澳门葡京备用网址 10

那样看其实也挺清楚知道的,然则当网络请求十六线程并发时,上面的日志就有极大希望变为如下:

澳门葡京备用网址 11

那时你还能够收看什么人是哪个人的参数,哪个人是什么人的结果吗,肯定是不行的,而日志的拼接组合就是为了化解那个题材,大家先来探视下边的日志输出:

澳门葡京备用网址 12

见状这么的输出是还是不是进一步的掌握明白,那那个日志是何等输出的啊?如下:

//拼接合并输出
UELog.append("POST  http://www.baidu.com/api/gps");
UELog.append("请求参数");
UELog.appendJson("{\"id\":221}");
UELog.append("返回结果");
UELog.json("{\"name\":\"my name is ueueo\",\"desc\":\"this is description!\"}");

UELog提供了append方法,能够对反复要出口的情节开始展览拼接,然后最终贰次行的输出,append方法有:

UELog.append("字符串");//拼接字符串
UELog.appendJson("{\"id\":221}");//拼接Json字符串
UELog.appendXml("<html></html>");//拼接Xml字符串
UELog.appendObject(obj);//拼接对象

也足以如此拼接:

UELog.append("字符串").appendJson("{\"id\":221}").appendXml("<html></html>").appendObject(obj).i("输出");

append办法并不会进展日志输出,唯有调用了日志输出方法才会最后输出的控制台,输出方法就是:

UELog.v("verbose level log");
UELog.d("debug level log");
UELog.i("info level log");
UELog.w("warn level log");
UELog.e("error level log");
UELog.wtf("assert level log");
UELog.json("json string log");
UELog.xml("xml string log");
UELog.object(obj);

注意:

  • 内部json,xml和object的输出都以以debug等级输出的;
  • append措施的调用必须是在同一线程内才使得,所以最佳确认保证你的append办法的调用都是在同1个办法里,而且调用日志输出方法输出日志之后,append东拼西凑的日记将被清空,再一次打字与印刷的日记将未有事先的拼凑新闻;

    是具备指标的超类,它的功效是回去三个字符串,那个字符串由
 调用它的类的类名 + @ + 调用它的类的哈希值十陆进制表示格局  组成。

作者 UEUEO

简书主页:http://www.jianshu.com/u/7adf23444c8d

有啥难点要么提议欢迎在简书上给本人留言,多谢~

    即 :getClass().getName() + ‘@’ +
Integer.toHexString(hashCode())

  由以上五个原因应该能够得到地点输出结果是由什么导致的了。

 

那么如何让自家定义的数目直接通过System.out.println输出其值呢 ?

 

我认为:

 对于System.out.println()帮衬的数据类型例如: int 、 double、char【】
等足以一向输出其值。

对此Object类型的数码,可以重写它的toString()
方法,遵照本身的想法输出。因为System.out.println输出object类型值时就是调用其toString方法。

对此System.out.println不帮助的数据类型例如 : int[] / double[] /
String[] /boolean 等,能够运用类集,例如 ArrayList等,

1 ArrayList<Integer> intList = new ArrayList<Integer>();
2 intList.add(1);
3 intList.add(2);
4 intList.add(3);
5 intList.add(4);
6 System.out.println(intList);

那样就可以输出其值

澳门葡京备用网址 13

自然假如你对这么的输出不够满意,也1律能够重写ArrayLIst等类集框架的toString方法,因为System.out.println方法在输出ArrayList等类集变量时正是调用其toString方法。

 

相关文章

发表评论

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

*
*
Website