Python学习4

1.类
①定义:

class Student(Object) //括号里面填继承类,如果没有具体的继承类,就写Object
     //__innit__方法,和构造方法类似,self指向实例本身,初始化实例的时候不需要传入self这个参数
     def __init__(self, name, score):
         self.name = name
         self.score = score
     //在类中定义的方法第一个参数永远是`self`

②访问限制
1.在属性名称的前面加上__,属性就变成私有变量,外部无法访问。可以通过_Student__name来访问__name变量,但是建议不要这么干
2.变量前面加_的变量,意思就是“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”。
3.变量名类似__xxx__的变量是特殊变量,不是私有变量,可以直接访问
2.获取对象信息
①基本类型都可以用type()判断

type(123)
<type 'int'>

type('123')
<type 'str'>

type(abs)
<type 'builtin_function_or_method'>

type(a)//a是Animal类的一个实例
<class '__main__.Animal'>

type(123) == type(253)
True

Python还把每种type类型都定义好了常量,放在types模块里:

import types
type('abc') == types.StringType
True

type(u'abc') == type.UnicodeType
True   

type(str) == type.TypeType//有种类型就叫TypeType,是所有类型的本身

②isinstance()

isinstance(a,str)//a表示对象,str是判断a是否为str类型
//还可以判断是否为多种类型中的一种
isinstance(a, (str, unicode))

③dir()
如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:

['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

类似__xxx__的属性和方法在Python中是有特殊用途的,比如__len__方法返回长度,实际上是自动去调用该对象的__len__()方法len('ABC') 就等价于'ABC.__len__()'

还可以通过getattr()setattrhasattr来操纵一个对象的属性

hasattr(obj, 'x') //obj对象有'x'属性吗
serattr(obj, 'y', 19) // 给obj设置一个'y'属性
getattr(obj, 'y') //获取'y'属性

3.使用_slot_
①当我要为一个定义好的类增加一些功能时,可以给实例绑定上属性和方法:

//绑上属性
s = Student()
s.name = 'Jack'
print s.name
Jack
//绑上方法
def set_age(self, age):
     self.age = age

from types import MethodType
s.set_age = MethodType(set_age, s, Student)
s.setage(25)
s.age
25

//给一个实例绑定方法不影响其他实例,如果要给所有实例绑定方法,可以给class绑定方法:
Student.set_age = MethodType(set_score, None, Student)

②使用__slots__限制class的属性
在定义class的时候,定义一个__slots__变量,来限制这个class能添加的属性

clss Student(object):
    __slots__ = ('name', 'age')

//尝试添加属性
s = Student()
s.name = 'Jack'
s.age = '26'
s.score = '99' //以上两个属性都可以绑定,但是绑定`'score'`就会报错,因为`__slots__`里面没有它

注意:__slots__定义只对当前类起作用,对继承的子类不起作用,除非在子类也定义__slots__,此时子类可以绑定的属性就包括父类和子类__slots__中的所有属性

4.使用@property
绑定属性时,假如直接用以上的方法绑定,会把属性直接暴露出去,可以直接修改,不可靠。有一种方法是通过在类里面定义函数来实现设置属性,得到属性,但是调用的时候略显复杂。这时,用@property装饰器可以把方法变成属性来简单的调用:

class Student(object):

    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
           raise ValueError('score must be an interger!')
        if value < 0 or value > 100:
           raise ValueError('score must be between 0~100!')
        self._score = value


s = Student()
s.score = 60 // 实际转化为s.set_score(60)
s.score //实际转化为s.get_score()
60

5.多重继承

当一个类要继承多个类的属性时class(父类1, 父类2),父类2及之后的类一般都是需要加入的额外功能,为了更好地看出继承关系,一般把父类2及其之后的类的类名加上后缀Mixin

6.定制类
看教程

7.使用元类
type()
使用type()动态创建类:

//定义类中要用的方法
def fn(self, name = 'world'):
    print('Hello, %s' %name)


//用type()创建类
Hello = type('Hello', (object,), dict(hello=fn)) 
//第一个传入的参数是类的`__name__`属性,等于号左边的名字是指向这个类的变量名,一般都取相同; 第二个传入的参数是类要继承的父类名称,用tuple的形式传入,所以只有一个元素时要记得加逗号; 第三个是用dict()将类中要创建的方法和已有函数绑定,想绑定多个时用逗号隔开即可

②元类 metaclass
看教程

8.错误处理
①try
和java相似:

try:
    print 'try...'
    r = 10 / int('a')
    print 'result:', r
except ValueError, e:
    print 'ValueError:', e
except ZeroDivisionError, e:
    print 'ZeroDivisionError:', e
else:
    print 'no error!'
finally:
    print 'finally...'
print 'END'

Python的错误都是class都是从BaseException类派生的,常见的错误类型和继承关系看下面链接
https://docs.python.org/2/library/exceptions.html#exception-hierarchy

②记录错误
如果不捕获错误,自然可以让Python解释器来打印出错误堆栈,但程序也被结束了。既然我们能捕获错误,就可以把错误堆栈打印出来,然后分析错误原因,同时,让程序继续执行下去。用Python内置的logging模块就可以记录错误信息:

import logging

def foo(s):
    return 10 / int(s)

def bar(s):
    return foo(s) * 2

def main():
    try:
        bar('0')
    except StandardError, e:
        logging.exception(e)

main()
print 'END'

结果是:

END
ERROR:root:integer division or modulo by zero
Traceback (most recent call last):
  File "D:/Workspace/PycharmProjects/test/Test", line 18, in main
    bar('0')
  File "D:/Workspace/PycharmProjects/test/Test", line 13, in bar
    return foo(s) * 2
  File "D:/Workspace/PycharmProjects/test/Test", line 9, in foo
    return 10 / int(s)
ZeroDivisionError: integer division or modulo by zero


raise抛出错误

9.单元测试&文档测试
看教程
https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/00140137128705556022982cfd844b38d050add8565dcb9000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值