• Python用法速查@类


    类和实例

    class Animal(object):...

    所有的类最终都继承自object类。
    类是具有相同方法属性的一组对象的集合。

    class Animal(object):
        pass
    
    

    animal = Animal()

    >>> animal = Animal()  # 创建一个实例对象
    >>> animal
    <__main__.Animal at 0x1030a44d0>
    
    

    animal = Animal(args)

    >>> animal = Animal('dog1')   # 传入参数 'dog1'
    >>> animal.name               # 访问对象的 name 属性
    'dog1'
    
    

    def __init__(self, name):...

    class Animal(object):
        def __init__(self, name): #初始化方法
            self.name = name
        def greet(self):
            print 'Hello, I am %s.' % self.name
    
    

    dog1.greet()

    >>> dog1 = Animal('dog1')
    >>> dog1.name
    'dog1'
    >>> dog1.greet()
    Hello, I am dog1.
    
    

    self.__name=name

    访问控制
    _a表示不要随意访问这个变量,虽然可以直接访问
    __name外部不可直接访问
    __name__特殊变量,可直接访问

    class Animal(object):
        def __init__(self, name):
            self.__name = name
        def greet(self):
            print 'Hello, I am %s.' % self.__name
    ----------------------------
    >>> dog1 = Animal('dog1')
    >>> dog1.__name   # 访问不了
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-206-7f6730db631e> in <module>()
    ----> 1 dog1.__name
    
    AttributeError: 'Animal' object has no attribute '__name'
    >>> dog1.greet()   # 可以访问
    Hello, I am dog1.
    
    

    获取对象信息

    type(obj)

    isinstance(obj, class)

    >>> dog1 = Animal('dog1')
    >>> type(dog1) #获取对象类型
    __main__.Animal
    >>> isinstance(dog1, Animal)#对象是否为对应类型
    True
    
    

    hasattr(obj, attr)

    getattr(obj, attr[, default])

    setattr(obj, attr, value)

    >>> hasattr(dog1, 'name')#对象是否有对应属性
    True
    >>> hasattr(dog1, 'x')
    False
    >>> hasattr(dog1, 'greet')#对象是否有对应方法
    True
    >>> getattr(dog1, 'name')#获取属性值
    'dog1'
    >>> getattr(dog1, 'greet')#获取方法
    <bound method Animal.greet of <__main__.Animal object at 0x10c3564d0>>
    >>> getattr(dog1, 'x')
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-241-42f5b7da1012> in <module>()
    ----> 1 getattr(dog1, 'x')
    
    AttributeError: 'Animal' object has no attribute 'x'
    >>> getattr(dog1, 'x', 'xvalue')#没有该属性时默认返回xvalue
    'xvalue'
    >>> setattr(dog1, 'age', 12)#设置属性值
    >>> dog1.age
    12
    
    

    dir(obj)

    #获取所有 方法名和属性 列表
    >>> dir(dog1)
    ['__class__',
     '__delattr__',
     '__dict__',
     '__doc__',
     '__format__',
     '__getattribute__',
     '__hash__',
     '__init__',
     '__module__',
     '__new__',
     '__reduce__',
     '__reduce_ex__',
     '__repr__',
     '__setattr__',
     '__sizeof__',
     '__str__',
     '__subclasshook__',
     '__weakref__',
     'age',
     'greet',
     'name']
    
    
    

    继承

    class Dog(Animal):

    子类可以在父类基础上覆盖和添加方法

    class Animal(object):
        def __init__(self, name):
            self.name = name
        def greet(self):
            print 'Hello, I am %s.' % self.name
    
    class Dog(Animal):
        def greet(self):
            print 'WangWang.., I am %s. ' % self.name
    
    #结果
    >>> animal = Animal('animal')  # 创建 animal 实例
    >>> animal.greet()
    Hello, I am animal.
    >>> 
    >>> dog = Dog('dog')        # 创建 dog 实例
    >>> dog.greet()
    WangWang.., I am dog. 
    
    
    class Dog(Animal):
        def greet(self):
            print 'WangWang.., I am %s. ' % self.name
        def run(self):
            print 'I am running.I am running'
    
    #结果
    >>> dog = Dog('dog')
    >>> dog.greet()
    WangWang.., I am dog.
    >>> dog.run()
    I am running
    
    

    多态

    obj.method()

    多态不同的对象对同一消息作出不同的响应

    class Animal(object):
        def __init__(self, name):
            self.name = name
        def greet(self):
            print 'Hello, I am %s.' % self.name
    
    class Dog(Animal):
        def greet(self):
            print 'WangWang.., I am %s.' % self.name
            
    class Cat(Animal):
        def greet(self):
            print 'MiaoMiao.., I am %s' % self.name
            
    def hello(animal):
        animal.greet()
    
    
    #结果
    >>> dog = Dog('dog')
    >>> hello(dog)
    WangWang.., I am dog.
    >>>
    >>> cat = Cat('cat')
    >>> hello(cat)
    MiaoMiao.., I am cat
    
    

    类方法

    @classmethod=>cls.method()

    上面都是通过实例来调用方法,Python 提供了@classmethod装饰器让我们也可以用类调用方法。

    class A(object):
        bar = 1
        @classmethod
        def class_foo(cls): #参数cls是class A(object):类本身
            print 'Hello, ', cls
            print cls.bar #我们可以直接调用类的方法
    
    >>> A.class_foo()   # 直接通过类来调用方法
    Hello,  <class '__main__.A'>
    1
    
    

    静态方法

    @staticmethod=>cls.method()

    某些不改变类和实例状态,但又和类有关系的方法。我们用@staticmethod来装饰。

    class A(object):
        bar = 1
        @staticmethod
        def static_foo(): #静态方法无cls参数,可以写到类外面,但这将不利于 代码的组织 和 命名空间的整洁
            print 'Hello, ', A.bar
    
    >>> a = A()
    >>> a.static_foo()
    Hello, 1
    >>> A.static_foo()
    Hello, 1
    
    

    定制类和魔法方法

    常见魔法方法(特殊方法)

    
        __new__
        __str__ , __repr__
        __iter__
        __getitem__ , __setitem__ , __delitem__
        __getattr__ , __setattr__ , __delattr__
        __call__
    
    
    

    def __new__(cls):...=>obj=Class()

    def __init__(self):...

    __new____init__之前执行,我们可用此方法控制实例的创建过程。

    class A(object):
        _dict = dict()
    
        def __new__(cls): # 类方法
            if 'key' in A._dict:
                print "EXISTS"
                return A._dict['key']
            else:
                print "NEW"
                return object.__new__(cls)
    
        def __init__(self): # 实例方法
            print "INIT"
            A._dict['key'] = self
    
    # 结果
    >>> a1 = A()
    NEW
    INIT
    >>> a2 = A()
    EXISTS
    INIT
    >>> a3 = A()
    EXISTS
    INIT
    
    
    

    def __str__(self):...=>print(obj)

    __str__可用于备注类的详细信息

    class Foo(object):
        def __init__(self, name):
            self.name = name
        def __str__(self): # 在打印对象时自动调用
            return 'Foo object (name: %s)' % self.name
    
    >>> print Foo('ethan')      # 使用 print
    Foo object (name: ethan)
    >>>
    >>> str(Foo('ethan'))       # 使用 str
    'Foo object (name: ethan)'
    >>>
    >>> Foo('ethan')             # 直接显示
    <__main__.Foo at 0x10c37a490>
    
    

    def __repr__(self):...=>obj()

    上面直接显示时还是默认信息,如果我们想让直接显示的也是备注的详细信息

    class Foo(object):
        def __init__(self, name):
            self.name = name
        def __str__(self):
            return 'Foo object (name: %s)' % self.name
        def __repr__(self):
            return 'Foo object (name: %s)' % self.name
    
    >>> Foo('ethan')
    'Foo object (name: ethan)'
    
    

    class Foo(object):
        def __init__(self, name):
            self.name = name
        def __str__(self):
            return 'Foo object (name: %s)' % self.name
        __repr__ = __str__
    
    

    def __iter__(self):...=>for i in obj:...

    def __next__(self):...

    让实例可用于for循环

    class Fib(object):
        def __init__(self):
            self.a, self.b = 0, 1
    
        def __iter__(self):  # 返回迭代器对象本身
            return self      
    
        def next(self):      # 返回容器下一个元素
            self.a, self.b = self.b, self.a + self.b
            return self.a    
    
    >>> fib = Fib()
    >>> for i in fib:
    ...     if i > 10:
    ...         break
    ...     print i
    ...
    1
    1
    2
    3
    5
    8
    
    
    # -*- coding: utf-8 -*-
    # @Time : 2021/6/18 21:33
    # @Author : HUGBOY
    # @File : HelloYoutube.py
    # @Software: PyCharm
    
    
    class fiber(object):
        def __init__(self):
            self.a, self.b = 0, 1
        def __iter__(self):
            return self
        def __next__(self):
            self.a, self.b = self.b, self.a + self.b
            return self.a
    
    f = fiber()
    for i in f:
        print(i, end="~")
        if i >= 100:
            break
    		
    # 结果
    
    D:pythonpython.exe E:/PYTHON/Basics/Fun/HelloYoutube.py
    1~1~2~3~5~8~13~21~34~55~89~144~
    Process finished with exit code 0
    
    

    def __getitem__(self):...=>obj[n]/obj[a:b]

    实现用obj[n]方法来获取实例的值,如fiber数列。

    class Fib(object):
        def __getitem__(self, n):
            a, b = 1, 1
            for x in xrange(n):
                a, b = b, a + b
            return a
        
    >>> fib = Fib()
    >>> fib[0], fib[1], fib[2], fib[3], fib[4], fib[5]
    (1, 1, 2, 3, 5, 8)
    
    
    # -*- coding: utf-8 -*-
    # @Time : 2021/6/18 21:33
    # @Author : HUGBOY
    # @File : HelloYoutube.py
    # @Software: PyCharm
    
    
    class fiber(object):
        def __getitem__(self, n):
            a, b = 0, 1
            for i in range(n):
                a, b = b, a + b
            return a
    
    itemf = fiber()
    print(itemf[0], itemf[6], itemf[10])
    
    #结果
    D:pythonpython.exe E:/PYTHON/Basics/Fun/HelloYoutube.py
    0 8 55
    
    Process finished with exit code 0
    
    
    

    在上面的基础上实现分片slics

    # -*- coding: utf-8 -*-
    # @Time : 2021/6/18 21:33
    # @Author : HUGBOY
    # @File : HelloYoutube.py
    # @Software: PyCharm
    
    
    class sFiber():
        def __getitem__(self, n):
            if isinstance(n, int): #判断参数n是否为 int 类型
                a, b = 0, 1
                for i in range(n+1):
                    a, b = b, a + b
                    if i == n:
                        return a
            if isinstance(n, slice):#判断参数n是否为 slice对象 类型
                a, b = 0, 1
                start, stop = n.start, n.stop
                lis = []
                for i in range(stop+1):
                    a, b = b, a + b
                    if i >= start:
                        lis.append(a)
    
                return lis
    
    sf = sFiber()
    print(sf[2:9], sf[2], sf[9])
    
    # 结果
    D:pythonpython.exe E:/PYTHON/Basics/Fun/HelloYoutube.py
    [2, 3, 5, 8, 13, 21, 34, 55] 2 55
    
    Process finished with exit code 0
    

    def __setitem__(self):...=>obj['key']=value/len(obj)

    def __delitem__(self):...=>del obj['key']

    类似def __getitem__(self):...获取值,它们分别用于设置值,删除值

    class Point(object):
        def __init__(self):
            self.coordinate = {}
    
        def __str__(self):
            return "point(%s)" % self.coordinate
    
        def __getitem__(self, key):
            return self.coordinate.get(key)
    
        def __setitem__(self, key, value):
            self.coordinate[key] = value
    
        def __delitem__(self, key):
            del self.coordinate[key]
            print 'delete %s' % key
    
        def __len__(self):
            return len(self.coordinate)
            
        __repr__ = __str__
    
    # 结果
    >>> p = Point()
    >>> p['x'] = 2    # 对应于 p.__setitem__('x', 2)
    >>> p['y'] = 5    # 对应于 p.__setitem__('y', 5)
    >>> p             # 对应于 __repr__
    point({'y': 5, 'x': 2})
    >>> len(p)        # 对应于 p.__len__
    2
    >>> p['x']        # 对应于 p.__getitem__('x')
    2
    >>> p['y']        # 对应于 p.__getitem__('y')
    5
    >>> del p['x']    # 对应于 p.__delitem__('x')
    delete x
    >>> p
    point({'y': 5})
    >>> len(p)
    1
    
    

    def __getattr__(self):...=>obj.x

    当我们获取某个属性不存在时,会报错

    class Point(object):
        def __init__(self, x=0, y=0):
            self.x = x
            self.y = y
    
    >>> p = Point(3, 4)
    >>> p.x, p.y
    (3, 4)
    >>> p.z
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-547-6dce4e43e15c> in <module>()
    ----> 1 p.z
    
    AttributeError: 'Point' object has no attribute 'z'
    
    

    __getattr__方法防止报错

    class Point(object):
        def __init__(self, x=0, y=0):
            self.x = x
            self.y = y
        def __getattr__(self, attr):
            if attr == 'z':#访问z,返回0,如果访问其他的如w会默认返回None
                return 0
    
    >>> p = Point(3, 4)
    >>> p.z
    0
    
    

    还可以加入异常处理

    def __getattr__(self, attr):
        if attr == 'z':
            return 0
        raise AttributeError("Point object has no attribute %s" % attr)
    

    def __setattr__(self):...=>obj.x=value

    def __delattr__(self):...=>del obj.x

    class Point(object):
        def __init__(self, x=0, y=0):
            self.x = x
            self.y = y
    
        def __getattr__(self, attr):
            if attr == 'z':
                return 0
            raise AttributeError("Point object has no attribute %s" % attr)
    
        def __setattr__(self, *args, **kwargs):  
            print 'call func set attr (%s, %s)' % (args, kwargs)
            return object.__setattr__(self, *args, **kwargs)
    
        def __delattr__(self, *args, **kwargs):  
            print 'call func del attr (%s, %s)' % (args, kwargs)
            return object.__delattr__(self, *args, **kwargs)
        
    >>> p = Point(3, 4)
    call func set attr (('x', 3), {})
    call func set attr (('y', 4), {})
    >>> p.z
    0
    >>> p.z = 7
    call func set attr (('z', 7), {})
    >>> p.z
    7
    >>> p.w
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 8, in __getattr__
    AttributeError: Point object has no attribute w
    >>> p.w = 8
    call func set attr (('w', 8), {})
    >>> p.w
    8
    >>> del p.w
    call func del attr (('w',), {})
    >>> p.__dict__
    {'y': 4, 'x': 3, 'z': 7}
    
    

    def __call__(self):...=>callable(obj)

    一般用obj.method()调用对象,我们也可以用callable()直接在实例本身上调用

    class Point(object):
        def __init__(self, x, y):
            self.x, self.y = x, y
        def __call__(self, z):
            return self.x + self.y + z
    
    # 结果
    >>> p = Point(3, 4)
    >>> callable(p)     # 使用 callable 判断对象是否能被调用
    True
    >>> p(6)            # 传入参数,对实例进行调用,对应 p.__call__(6)
    13                  # 3+4+6
    
    

    slots 魔法

    obj.new_x=value

    给实例绑定新的属性和方法

    class Point(object):    
        def __init__(self, x=0, y=0):
            self.x = x
            self.y = y
    
    >>> p = Point(3, 4)
    >>> p.z = 5    # 绑定了一个新的属性
    >>> p.z
    5
    >>> p.__dict__
    {'x': 3, 'y': 4, 'z': 5}
    
    

    def __slots__(self):...=>obj.some_x=value

    限制绑定的属性

    class Point(object):
        __slots__ = ('x', 'y')       # 只允许使用 x 和 y
    
        def __init__(self, x=0, y=0):
            self.x = x
            self.y = y
    
    >>> p = Point(3, 4)
    >>> p.z = 5
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-648-625ed954d865> in <module>()
    ----> 1 p.z = 5
    
    AttributeError: 'Point' object has no attribute 'z'
    
    

    注意:子类只有使用slots魔法后才会继承父类的slots元组,组成tuple=child_slots_tuple+father_slots_tuple

    @property=>obj.method

    @method.setter=>obj.method=value

    被@property装饰器,装饰过的方法可以当做属性来用

    class Exam(object):
        def __init__(self, score):
            self._score = score
    
        @property
        def score(self):
            return self._score
    
        @score.setter
        def score(self, val):
            if val < 0:
                self._score = 0
            elif val > 100:
                self._score = 100
            else:
                self._score = val
    
    >>> e = Exam(60)
    >>> e.score
    60
    >>> e.score = 90
    >>> e.score
    90
    >>> e.score = 200
    >>> e.score
    100
    
    
    

    也可以不用@score.setter赋值装饰器

    class Exam(object):
        def __init__(self, score):
            self._score = score
    
        @property
        def score(self):
            return self._score
    
    >>> e = Exam(60)
    >>> e.score
    60
    >>> e.score = 200  # score 是只读属性,不能设置值
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-676-b0515304f6e0> in <module>()
    ----> 1 e.score = 200
    
    AttributeError: can't set attribute
    
    
    

    参考


    ________________________________________________________

    Every good deed you do will someday come back to you.

    Love you,love word !
  • 相关阅读:
    sql语句相关操作
    点菜系统数据库课程设计
    JDBC连接mysql编程
    JFrame画图基础和事件监听
    JFrame编程
    Java基础知识
    bzoj1047-理想的正方形(二维单调队列)
    Project Eular 233/ BZOJ 1041
    Open Train 10352
    Codeforces Round 492 (Div.1)
  • 原文地址:https://www.cnblogs.com/hugboy/p/python_class.html
Copyright © 2020-2023  润新知