面向对象高级编程
使用__slots__
因为python是一门动态语言,所以无法避免的会有给一个实例添加各种的属性或者方法的情况,python可以使用这个来限制实力的属性。
class Student(object):
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称
但是我觉得这样也不是很好,如果有很多属性的话岂不是都写一长串,而且如果有人忘写了,还是不可避免的出现之前那种说过的情况。总而言之,语言不会去限制你怎么写,一切靠自觉。
@property
看到这个的第一感觉就是类似Object-C
里面的property;
只需要在属性对应的get函数
前面加上@property
,则可以实现get方法;在set函数
前面加上属性.setter
,则可以实现set方法;
多继承
在类定义的时候,可以在括号里面加上多个类从而实现多继承;
class Dog(Animal,Friend) //狗是一种动物也是一种朋友
运算符重载
运算符重载意味着在类方法中拦截内置的操作-当类的实例出现在内置操作中,python自然会调用你的方法,比如我们一直使用的__init__
;
类可以重载所有Python表达式运算符,像是打印、函数调用、属性点号运算等内置运算
常见运算符重载方法包括以下:
枚举类
像是在c++
中的enum
,使用方法如下:
from enum import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
元类
元类就是用来创建类的东西,包括:
- 拦截类的创建;
- 修改类;
- 返回修改后的类;
个人觉得这是一个黑魔法,一般项目中应该不会用到,同时使用者要很小心,而且要很清楚自己在干嘛。
type
type
函数除了可以帮我们获取对象的类型,还可以帮我们创建对象,其描述为:
type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
举个例子:
# 我们可以这么做
class MyClass(object):
bar = True
# 也可以这么做
Foo = type('Foo', (), {'bar':True})
上面两种方法达到的目的是一样的,都能够创建一个类,但正常情况下不建议这么使用;
metaclass
除了使用type
可以动态的创建类意外,还可以使用metaclass
;
class Foo(object):
__metaclass__ = dosomething
如果这么做的话,python就不会使用内建的type来创建这个类,而是使用你自己定义的元类来创建,python会做这么一个操作:
首先写下class Foo(object),但是类对象Foo还没有在内存中创建。Python会在类的定义中寻找__metaclass__属性,如果找到了,Python就会用它来创建类Foo,如果没有找到,就会用内建的type来创建这个类。
例子:
# 请记住,'type'实际上是一个类,就像'str'和'int'一样
# 所以,你可以从type继承
class UpperAttrMetaClass(type):
# __new__ 是在__init__之前被调用的特殊方法
# __new__是用来创建对象并返回之的方法
# 而__init__只是用来将传入的参数初始化给对象
# 你很少用到__new__,除非你希望能够控制对象的创建
# 这里,创建的对象是类,我们希望能够自定义它,所以我们这里改写__new__
# 如果你希望的话,你也可以在__init__中做些事情
# 还有一些高级的用法会涉及到改写__call__特殊方法,但是我们这里不用
def __new__(upperattr_metaclass, future_class_name, future_class_parents, future_class_attr):
attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__'))
uppercase_attr = dict((name.upper(), value) for name, value in attrs)
return super(UpperAttrMetaClass, upperattr_metaclass).__new__(upperattr_metaclass, future_class_name, future_class_parents, uppercase_attr)
class Foo(object):
bar = "happy"
def echo_bar(self):
print(self.bar)
myclass = UpperAttrMetaClass('FooChild', (Foo,), {})
my = myclass()
my.echo_bar() #输出happy
错误、调试和测试
错误处理
类似于c++中的try...catch,python也有类似的错误处理函数:
try...
except: division by zero
finally...
例子:
try:
print('try...')
r = 10 / int('a')
print('result:', r)
except ValueError as e:
print('ValueError:', e)
except ZeroDivisionError as e:
print('ZeroDivisionError:', e)
finally:
print('finally...')
print('END')
你还可以使用内置的logging来纪录错误信息:
import logging
def main():
try:
bar('0')
except Exception as e:
logging.exception(e)
总结
到这里,我觉得最基本的语法已经学完了,接下来的包括:
- IO编程
- 异步编程
- 进程和线程编程
- 网络编程
- 数据库编程
这些编程都是用到的时候再来查询总结。