Python【第七篇】面向对象进阶

大纲

一、面向对象高级语法

  1.静态方法、类方法、属性方法

  2.类的特殊成员方法

  3.反射

二、异常处理

三、网络编程之socket基础

一、面向对象高级语法

1.静态方法:名义上归类管理,实际上静态方法里访问不了类或者实例中的任何属性
 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

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

     @staticmethod  # 实际上跟类没什么关系
     def eat():
         print("%s is eating.." % "hehe")

 d = Dog("Baker")
 d.eat()
 # 运行结果:hehe is eating..

 # 如果改成这样:
 # @staticmethod  # 实际上跟类没什么关系
 #     def eat(self):
 #         print("%s is eating.." % self.name)
 # 则会报错 :TypeError: eat() missing 1 required positional argument: 'self'.
 # 这说明:静态方法:名义上归类管理,实际上静态方法里访问不了类或者实例中的任何属性
2.类方法:只能访问类变量,不能访问实例变量
# _*_ coding:utf-8 _*_
__author__ = "ZingP"

class Dog(object):
    name = "xiaohu"

    def __init__(self, name):
        self.name = name

    @classmethod  # 类方法
    def eat(self):
        print("%s is eating.." % self.name)

d = Dog("Baker")
d.eat()

# 运行结果:xiaohu is eating..
# 可以看出这里结果并不是Baker is eating..,说明调用的self.name是类变量,不是实例变量

3.属性方法:把一个方法变成类的私有属性

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

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

     @property
     def eat(self):
         print("%s is eating..." % self.name)

 d = Dog("baker")
 # d.eat()  这样会报错:TypeError: 'NoneType' object is not callable,这是eat已是静态属性,而非方法
 d.eat      # 这样才是正确的调用方法
 # 运行结果:baker is eating...
 # @property 利用这个装饰器,把一个方法变成类的私有属性,调用就是:d.eat

3.1属性方法还可以这么用:

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

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

     @property
     def eat(self):
         print("%s is eating %s..." % (self.name, self.__food))

     @eat.setter
     def eat(self, food):
         print("set food:%s" % food)
         self.__food = food

 d = Dog("baker")
 d.eat              # 运行结果:baker is eating bone...
 d.eat = "beef"     # 运行结果:set food:beef
 d.eat              # 运行结果:baker is eating beef... 

3.2属性方法3:删除属性

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

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

     @property
     def eat(self):
         print("%s is eating %s..." % (self.name, self.__food))

     @eat.setter
     def eat(self, food):
         print("set food:%s" % food)
         self.__food = food

     @eat.deleter
     def eat(self):
         del self.__food
         print("'__food'已删除。")

 d = Dog("baker")
 d.eat = "beef"
 d.eat             # result: baker is eating None...
 del d.eat       # '__food'已删除。
 d.eat     # result: AttributeError: 'Dog' object has no attribute '_Dog__food'   

例: 把一个方法变成静态属性有什么卵用呢?既然想要静态变量,那直接定义成一个静态变量不就得了么?well, 以后你会需到很多场景是不能简单通过 定义 静态属性来实现的, 比如 ,你想知道一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态你必须经历以下几步:

1. 连接航空公司API查询

2. 对查询结果进行解析

3. 返回结果给你的用户

因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以,明白 了么?

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

     def checking_status(self):
         print("checking flight %s status " % self.flight_name)
         return  1

     @property
     def flight_status(self):
         status = self.checking_status()
         if status == 0 :
             print("flight got canceled...")
         elif status == 1 :
             print("flight is arrived...")
         elif status == 2:
             print("flight has departured already...")
         else:
             print("cannot confirm the flight status...,please check later")

 f = Flight("CA980")
 f.flight_status

那现在我只能查询航班状态, 既然这个flight_status已经是个属性了, 那我能否给它赋值呢?试试吧

 f = Flight("CA980")
 f.flight_status
 f.flight_status =  2

输出, 说不能更改这个属性,。。。。,怎么办怎么办???。。。

 checking flight CA980 status
 flight is arrived...
 Traceback (most recent call last):
   File "/Users/jieli/PycharmProjects/python基础/自动化day7面向对象高级/属性方法.py", line 58, in <module>
     f.flight_status =  2
 AttributeError: can't set attribute

当然可以改, 不过需要通过@proerty.setter装饰器再装饰一下,此时 你需要写一个新方法, 对这个flight_status进行更改。

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

    def checking_status(self):
        print("checking flight %s status " % self.flight_name)
        return  1

    @property
    def flight_status(self):
        status = self.checking_status()
        if status == 0 :
            print("flight got canceled...")
        elif status == 1 :
            print("flight is arrived...")
        elif status == 2:
            print("flight has departured already...")
        else:
            print("cannot confirm the flight status...,please check later")

    @flight_status.setter #修改
    def flight_status(self,status):
        status_dic = {
            0 : "canceled",
            1 :"arrived",
            2 : "departured"
        }
        print("\033[31;1mHas changed the flight status to \033[0m",status_dic.get(status) )

    @flight_status.deleter  #删除
    def flight_status(self):
        print("status got removed...")

f = Flight("CA980")
f.flight_status
f.flight_status =  2 #触发@flight_status.setter
del f.flight_status #触发@flight_status.deleter

注意以上代码里还写了一个@flight_status.deleter, 是允许可以将这个属性删除 。

4.类的特殊成员方法:

1).__doc__ :表示类的描述信息

 class Dog(object):
     """This is uesed in discribing info of the class."""

     def __init__(self, name):
         self.name = name

 print(Dog.__doc__)
 # result: This is uesed to discribe info of the class.
 # __doc__ ,It is uesed to discribe info of the class.

2).__call__:

# _*_ coding:utf-8 _*_
__author__ = "ZingP"

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

    @property
    def eat(self):
        print("%s is eating..." % self.name)

    def __call__(self, *args, **kwargs):
        print("This is call:", args, kwargs)

d = Dog("baker")
Dog("baker")()                          # 运行结果:This is call: () {}
Dog("baker")(1, 2, 3, name="xiaohu")    # 运行结果:This is call: (1, 2, 3) {'name': 'xiaohu'}
# __call__函数可以在实例函数后面加(),传参数,直接执行。

3).__module__ 和  __class__

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

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

# _*_ coding:utf-8 _*_
__author__ = "ZingP"

from __call__ import Dog

d = Dog("Baker")
print(d.__module__)   # result:  __call__
print(d.__class__)    # result:  <class '__call__.Dog'>

4).__dict__ 查看类或对象中的所有成员

# _*_ coding:utf-8 _*_
__author__ = "ZingP"

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

    def func(self):
        print("My name is %s..." % self.name)

print(Dog.__dict__)
# result:
# {'__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__module__': '__main__', 'n': 3,
# '__init__': <function Dog.__init__ at 0x01CBE228>, 'func': <function Dog.func at 0x01CBE1E0>, '__doc__': None}

5).__getitem__、__setitem__、__delitem__

用于索引操作,如字典。以上分别表示获取、设置、删除数据

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

 class Foo(object):
     def __getitem__(self, key):
         print('__getitem__', key)

     def __setitem__(self, key, value):
         print('__setitem__', key, value)

     def __delitem__(self, key):
         print('__delitem__', key)

 obj = Foo()
 result = obj['k1']  # 自动触发执行 __getitem__
 obj['k2'] = 'alex'  # 自动触发执行 __setitem__
 del obj['k1']
 print(obj.__getitem__)
 # __getitem__ k1
 # __setitem__ k2 alex
 # __delitem__ k1
 # <bound method Foo.__getitem__ of <__main__.Foo object at 0x015CA3F0>>

6).__init__/__del__ 构造函数和析构函数见上一篇day6【面向对象】

7).__new__/__metaclass__见Alex博客,且这讲的是python2机制,与python3有差别

8).__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

 class Foo:

     def __str__(self):
         return 'zingp'

 obj = Foo()
 print obj
 # result:zingp

5.反射:通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

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

     def eat(self):
         print("%s is eating..." % self.name)

 d = Dog("baker")

 def tell(self):
     print("my name is %s..." % self.name)

 choice = input(">>>:")
 if hasattr(d, choice):          # hasattr(obj, 'name')检查是否含有成员
     getattr(d, choice)()        # getattr(obj, 'name')这里是返回类中字符串choice对应的方法的内存地址,加()调用
 else:
     # setattr(d, choice, 22)     # 为实例添加属性
     setattr(d, choice, tell)     # setattr(obj,'name',func)这里是输入的choice字符串 对应的方法为tell()
     func = getattr(d, choice)
     func(d)
 delattr(d,choice)                # delattr(obj, 'name') 删除成员
 # 比如 输入的choice是  "talk" ,相当于给实例d增加了方法:  def talk(self):
 #                                                    tell(self)
 # 而 d.choice ---->d."talk"  所以不对,d.tell 则会报错说d这个对象没有tell属性,因为有talk属性,没有tell属性。
 #

二、异常处理

1.一般异常

# _*_ coding:utf-8 _*_
__author__ = "ZingP"

name = ["zing-p", "nancy", "baby"]
data = {"name": "zing-p"}

try:
    # name[4]
    data["key"]
except IndexError as e:       # 多个错误可写成:(IndexError, KeyError)
    print(e)
except KeyError as e:
    print("没有这个key", e)
except Exception as e:
    print("未知错误:", e)
else:
    print("try 中没有错误,执行else。")
finally:
    print("不管有没有错,都执行finally。")
# result:
# 没有这个key 'key'
# 不管有没有错,都执行finally。

2.自定义异常:

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

 class MyError(Exception):
     def __init__(self, msg):
         self.message = msg
     # def __str__(self):
     #     return 'sdfsf'
 try:
     raise MyError('数据库连不上')
 except MyError as e:
     print(e)
 # result:数据库连不上

三.socket编程:

server端:

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

 import socket

 server = socket.socket()            # 声明
 server.bind(("localhost", 9000))    # 绑定监听端口
 server.listen()                     # 开始监听

 conn, addr = server.accept()        # conn就是客户端连过来,服务器为其生成的一个连接实例。
 data = conn.recv(1024)              # 接收数据
 conn.send(data.upper())             # 返回数据

 server.close()

client端

 # _*_ coding:utf-8 _*_
 __author__ = "ZingP"

 import socket

 client = socket.socket()                # 声明
 client.connect(("localhost", 9000))     # 连接

 client.send(b"hello world!")            # 发送请求
 # client.send("我是zing-p".encode("utf-8"))
 data = client.recv(1024)                # 接收数据
 print("recv:", data)                    # 打印接收数据

 client.close()

更多:http://www.cnblogs.com/wupeiqi/articles/5040823.html

 

上一篇:onclick事件触发 input type=“file” 上传文件


下一篇:【python自动化第七篇:面向对象进阶】