定制类

python定制类主要是实现特定功能,通过在类中定义特定的函数完成特定的功能。

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

student = Student("lilei")
print(student)

str用法

class Student(object):
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return ("self name is %s" %(self.name))

student2 = Student("hanmeimei")
print(student2)

实现__str__函数,可以在print类对象时打印指定信息

通过实现__iter____next__同样可以使类对象产生可迭代序列,下面实现了斐波那契数列

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
        if self.a > 30:
            raise StopIteration()
        return self.a

__iter__返回一个可迭代对象,这里我们返回了Fib自己的对象。 __next__是根据迭代器返回每一个迭代的序列,这里实现了运算规则,返回对象的a成员。 打印输出

for n in Fib():
    print(n)

getitem用法

可以实现__getitem__函数,这样就可以按照索引访问类对象中迭代元素了。

class OddNum(object):
    def __init__(self):
        self.num = -1
    def __iter__(self):
        return self
    def __next__(self):
        self.num = self.num +2
        if self.num > 10:
            raise StopIteration()
        return self.num 

    def __getitem__(self,n):
        temp = 1
        for i in range(n):
            temp += 2
        return temp
for n in OddNum():
    print(n)

oddnum = OddNum()
print(oddnum[3])

可以进一步完善OddNum类的__getitem__函数,使其支持切片处理

def __getitem__(self, n):
    if isinstance(n ,int):
        temp =1
        for i in range(n):
            temp +=2
        return temp
    if isinstance(n, slice):
        start = n.start
        end = n.stop
        if start is None:
            start = 0
        tempList = []
        temp = 1
        for i in range(end):
            if i >= start:
                temp += 2
                tempList.append(temp)
        return tempList

可通过如下方式调用 print(oddnum[1:4])

getattr用法

通过实现__getattr__函数,可以在类对象中没有某个属性时,自动调用__getattr__函数 实现__call__函数,可以实现类对象的函数式调用

def __getattr__(self,attr):
    if attr == 'name':
        return 'OddNum'
    if attr == 'data':
        return lambda:self.num
    raise AttributeError('\'OddNum\' object has no attribute \'%s\'' %attr)
def __call__(self):
    return "My name is OddNum!!"

只有在没有找到属性的情况下,才调用__getattr__,已有的属性不会在__getattr__中查找。

print(oddnum.name)
print(oddnum.data)
#没有func函数会抛出异常
#print(oddnum.func)
#可以直接通过oddnum()函数式调用
print(oddnum())

定制类案例

下面是一个链式转化例子,用到了这些特定函数

class Chain(object):
    def __init__(self, path=''):
        self.path = path
    def __getattr__(self,attr):
        return Chain('%s/%s'%(self.path, attr))
    def users(self, users):
        return Chain('%s/users/%s' %(self.path, users))
    def __str__(self):
        return self.path
    __repr__ = __str__
print(Chain().users('michael').repos)

repr表示一个对象的字符串显示,当我们打印这个对象时,如果没有实现str函数,则会调用repr函数。 另外,当我们打印datetime对象时,可以看到repr相比str目标更具有准确性,str目标在于可读性。 另外,在迭代器迭代打印的时候默认调用的是对象的repr函数。 所以在我们实现了str方法后,基本也会将其赋值给repr函数。 具体的参考连接https://www.cnblogs.com/miaoning/p/11399575.html 因为我们定义了getattr函数,所以当属性不存在时就会构造一个新的对象返回,返回的对象拼接了之前的path信息和attr属性。 我们定义了users函数,这样可以调用users函数了。但是我们可以用更简洁的办法实现各种函数的调用而不用定义他们,就是通过实现call函数,这样就可以实现链式调用。

class Chain(object):
    def __init__(self, path=''):
        self.path = path
    def __getattr__(self,attr):
        return Chain('%s/%s'%(self.path, attr))
    def __call__(self, param):
        return Chain('%s/%s'%(self.path, param))
    def __str__(self):
        return self.path
    __repr__ = __str__

print(Chain().get.users('michael').group('doctor').repos)

当调用users('michael')时,因为没有定义users函数,所以会调用getattr函数,进而构造一个新的Chain对象。因为实现了call函数,所以这个对象可以被当作函数来使用,也就是Chain('michael')的方式。

enum枚举

python同样支持枚举操作

from enum  import Enum
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec') )
for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)

from enum import  unique
@unique
class Weekday(Enum):
    Sun = 0 # Sun的value被设定为0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6

for name , member in Weekday.__members__.items():
    print(name, '=>', member, ',', member.value)

results matching ""

    No results matching ""