python学习笔记7--面向对象进阶,异常处理,socket编程初识

一、类的特殊方法

  1、静态方法

  静态方法只是封装在类中的一个普通函数,其和类没有什么关系,但只可以通过类来调用,不能访问实例或类中的任何属性。

  使用 @staticmethod 声明可以将一个方法声明为静态方法:

class Dog(object):
    def __init__(self,name):
        self.name = name
    
    @staticmethod  #将eat方法声明为静态方法
    def eat(self,food):
        print("%s正在吃%s" % (self.name,food))


dog1 = Dog("哈士奇")
dog1.eat("狗粮")

 

   上述代码会在运行时报错,原因在于eat方法要求传入self,food两个参数,而我们实际上只传入了一个参数。如果想避免这个错误,有两种方法:

  (1)、调用时传入自身

 

class Dog(object):
    def __init__(self,name):
        self.name = name

    @staticmethod
    def eat(self,food):
        print("%s正在吃%s" % (self.name,food))


dog1 = Dog("哈士奇")
dog1.eat(dog1,"狗粮")

  (2)、定义eat方法时去掉self参数,但是问题又出现了,去掉self后,就没法使用self来调用其他参数了

  2、类方法

  类方法只能访问类变量,不能访问实例变量

  使用 @classmethod 将一个方法声明为类方法

class Dog(object):
    def __init__(self,name):
        self.name = name

    @classmethod  #将eat方法声明为类方法
    def eat(self,food):
        print("%s正在吃%s" % (self.name,food))


dog1 = Dog("哈士奇")
dog1.eat("狗粮")


运行结果:
Traceback (most recent call last):
  File "/Users/zhanghaoyan/PycharmProjects/day07/blog_code.py", line 14, in <module>
    dog1.eat("狗粮")
  File "/Users/zhanghaoyan/PycharmProjects/day07/blog_code.py", line 10, in eat
    print("%s正在吃%s" % (self.name,food))
AttributeError: type object 'Dog' has no attribute 'name'

  上述代码运行结果可以看到,报错提示我们Dog类没有name属性,因为name属性是实例的属性,所以类方法没法访问。如果定义一个类变量叫name,那么就可以访问了。

  3、属性方法

  顾名思义,属性方法就是像调用一个类的属性一样的去调用一个方法,即在调用的时候不加()。这玩意儿看起来好没用的感觉,当调用一个外部接口时,我们是不需要知道外部接口是如何工作的,所以,为了装逼不被拆穿,我们就搞个属性方法出来:

class Dog(object):
    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s正在吃%s" % (self.name,food))


class Flight(object):
    def __init__(self,flight_num):
        self.num = flight_num

    def check_status(self):
        print("check flight %s status:" % self.num)
        return 1

    @property    #声明flight_status为属性方法
    def flight_status(self):
        status = self.check_status()
        status_dic = {
            1:"arrived!",
            2:"fling!",
            3:"late!"
        }
        print(status_dic[status])

flight1 = Flight("NH180")
flight1.flight_status


运行结果:
check flight NH180 status:
arrived!

  从上述代码中我们可以看到,在调用flight_status方法时,并没有(),而是像属性一般去调用。既然已经伪装成属性了,那我们更改一下这个属性的值:

class Dog(object):
    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s正在吃%s" % (self.name,food))


class Flight(object):
    def __init__(self,flight_num):
        self.num = flight_num

    def check_status(self):
        print("check flight %s status:" % self.num)
        return 1

    @property
    def flight_status(self):
        status = self.check_status()
        status_dic = {
            1:"arrived!",
            2:"fling!",
            3:"late!"
        }
        print(status_dic[status])

flight1 = Flight("NH180")
flight1.flight_status = 2
flight1.flight_status


运行结果:
Traceback (most recent call last):
  File "/Users/zhanghaoyan/PycharmProjects/day07/blog_code.py", line 31, in <module>
    flight1.flight_status = 2
AttributeError: can't set attribute
更改属性方法值

  从代码的运行结果看出,报错说不能更改属性,卧槽,暴露了,这逼装的一点都不像了,其实还是有方法让我们把这个逼装的更到位一些的:

class Dog(object):
    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s正在吃%s" % (self.name,food))


class Flight(object):
    def __init__(self,flight_num):
        self.num = flight_num

    def check_status(self):
        print("check flight %s status:" % self.num)
        return 1

    @property
    def flight_status(self):
        status = self.check_status()
        status_dic = {
            1:"arrived!",
            2:"fling!",
            3:"late!"
        }
        print(status_dic[status])

    @flight_status.setter
    def flight_status(self,status):
        self.check_status()
        status_dic = {
            1:"arrived!",
            2:"fling!",
            3:"late!"
        }
        print(status_dic[status])
    
    @flight_status.deleter
    def flight_status(self):
        print("删除了!")

flight1 = Flight("NH180")
flight1.flight_status = 2
del flight1.flight_status
运行结果: check flight NH180 status: fling!
删除了!

  从上述结果可以看出,我们对该属性方法做了更改甚至删除,这是因为,使用 @属性方法名.setter 这个方法可以设置该属性方法,其下修饰的是一个全新的与属性方法同名的新方法。而 @属性方法名.deleter 修饰可以删除该属性方法。

  3、类的特殊成员方法

  __doc__:打印类的描述信息

  __module__:表示当前操作的对象在哪个模块

  __class__:表示当前操作的对象的类是什么

  __call__:对象后面加括号,触发执行。构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

  __dict__:查看类或对象中的所有成员,以字典的方法打印出来,类调用时不包括实例属性,实例调用的时候不包括类属性

  __getitem__、__setitem__、__delitem__:操作索引

二、反射

  反射是指:通过字符串映射或修改程序运行时的状态、属性、方法:

  hasattr(obj,str):判断对象obj中是否有对应str的方法,是返回True,否返回False

  getattr(obj,str):返回对象obj中字符串str对应的方法的内存地址

  setattr(obj,str,new):新增方法或属性,其中new是要添加的方法或属性,需要提请定义好

  delattr(obj,str):删除obj.str方法 

class Dog(object):
    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s正在吃%s" % (self.name,food))


dog1 = Dog("单身狗")
print("hasattr: ",hasattr(dog1,"eat"))



运行结果:
hasattr:  True
hasattr
class Dog(object):
    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s正在吃%s" % (self.name,food))


dog1 = Dog("单身狗")
print("getattr: ",getattr(dog1,"eat"))




运行结果:
getattr:  <bound method Dog.eat of <__main__.Dog object at 0x101b78e80>>
getattr
def bulk(self):
    print("%s: 汪汪汪!!" % self.name)

class Dog(object):
    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s正在吃%s" % (self.name,food))


dog1 = Dog("单身狗")
setattr(dog1,"folk",bulk)
dog1.folk(dog1)



运行结果:
单身狗: 汪汪汪!!
setattr
class Dog(object):
    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s正在吃%s" % (self.name,food))


dog1 = Dog("单身狗")
print("before delete function eat,has eat?",hasattr(dog1,"eat"))
delattr(dog1,'eat')
print("after delete function eat,has eat?",hasattr(dog1,"eat"))


运行结果:
before delete function eat,has eat? True
after delete function eat,has eat? False
delattr

 

 三、异常处理

 1、在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面。

  try:
    code    #程序代码
  except (ERRORNAME,...,) as xx: #捕捉错误
    code    #捕捉到错误后执行的操作
  except ... as xxx:
    code    #将错误重命名
  else: 
    code    #没出错的时候执行else部分的代码
  finally: 
    code    #不管有错没错都执行finally中的代码

  万能异常 在python的异常中,有一个万能异常:Exception,他可以捕获任意异常,即:

  try:
    code
  except Exception:
     code

  2、常见及不常见异常:

  AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x

  IOError 输入/输出异常;基本上是无法打开文件

  ImportError 无法引入模块或包;基本上是路径问题或名称错误

  IndentationError 语法错误(的子类) ;代码没有正确对齐

  IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]

  KeyError 试图访问字典里不存在的键

  KeyboardInterrupt Ctrl+C被按下

  NameError 使用一个还未被赋予对象的变量

  SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)

  TypeError 传入对象类型与要求的不符合

  UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它

  ValueError 传入一个调用者不期望的值,即使值的类型是正确的

ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError
更多异常

 

  3、 自定义异常

class ourException(Exception):
 
    def __init__(self, msg):
        self.message = msg
 
    def __str__(self):
        return self.message
 
try:
    raise ourException('我的异常')
except ourException as e:
    print e

 

 更多异常相关:http://www.cnblogs.com/wupeiqi/articles/5017742.html

四、socket基础

参考:http://www.cnblogs.com/wupeiqi/articles/5040823.html 

posted @ 2016-09-09 11:07  没有手艺的手艺人  阅读(248)  评论(0编辑  收藏  举报