python高级(魔法方法,类方法,设置对象属性等)

1,python中的类方法、类实例、静态方法区别

# 类方法,实例方法,静态方法区别
class Test(object):
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    def song(self):
        print('实例方法')

    @classmethod
    def sing(cls, name,age,gender):  # cls,类对象
        obj = cls(name, age, gender)  # 类对象可以创建实例对象
        print('类方法')
        print(obj.name)
        print(obj.age)
        print(obj.gender)

    @staticmethod
    def say():
        print('静态方法')


test = Test('小明', 18, 1)
test.song()
test.say()
test.sing('小红')
  • 输出结果
实例方法
静态方法
类方法
小红
22
1
  • 类方法:是类对象的方法,在定义时需要在上方使用@classmethod进行修饰,形参为cls,表示类对象,类对象和实例对象都可以被调用
  • 类实例方法:是实例化对象的方法,只有实例对象可以调用,形参为self,指代对象本身
  • 静态方法:是一个任意函数,在其上方使用@staticmethod进行装饰,直接可以用对象直接调用
    • 静态方法实际上跟该类没有太大关系

2,python中如何获取和设置对象的属性

# hasattr(obj,"") 判断实例对象是否有指定实例属性或者实例方法、类方法、静方法、类属性
# 存在返回true,否则返回false
if hasattr(Parent,'x'): 
    print(getattr(Parent,'x'))  # getattr(obj,"") 从实例对象中获取指定实例属性或者实例方法、类方法、静方法、类属性
    # 获取的方法可以直接调用,属性可以在直接使用
    setattr(Parent,'x'3)   # setattr(obj,"","") 为实例对象设置指定实例属性或者实例方法
    print(getattr(Parent,'x'))

3,python函数调用的时候参数的传递方式是值传递还是引用传递?

  • 不可变类型的参数是传递 (int,str,tuple)
  • 可变类型的参数是引用 传递 (list,dict)

4,为什么函数名字可以作为参数用?

-python中一切皆对象,函数名是函数在内存中的空间,也是一个对象。

5,缺省(默认)参数和不定长参数、关键字参数

def demo(name='tom')
    print(name)
demo()
# 输出结果是 tom 
demo('jack')
# 输出结果是 jack 
  • 缺省参数是指在调用函数的时候没有传入参数的情况下,调用设定的默认值,如果传入参数,会使用传入的参数值
  • *args是不定长参数,它可以表示输入参数是不确定的,可以是任意多个
  • **kwargs是关键字参数,赋值的时候是以键=值的方式
def demo(*args, **kwargs):
'''函数声明,表示该函数可以接收不定长的参数和关键字参数'''
    demo(*args, **kwargs)  # 拆包

6,python中is和==的区别

  • is判断的是a对象是否就是b对象,是通过id来判断的
  • ==判断的是a对象的值是否和b对象的值相等,是通过value来判断的

7,python的魔法方法

  • __init__初始化方法,当实例被创建的时候调用
  • __new__ 是实例化对象调用的第一个方法
  • __call__ 允许一个类的实例对象像函数一样被调用
class A(object):
    def __call__(self):
        print("__call__ be called")

a = A()
a()
#输出
#__call__ be called 
  • __getitem__ 定义获取容器中指定的元素的行为,相当于self[key]
  • __getattr__ 是一旦我们尝试访问一个并不存在的属性的时候就会调用,而如果这个属性存在则不会调用该方法
class Test(object):
    def __init__(self, world):
        self.world = world

    def __getattr__(self, item):
        return item


x = Test('world123')
print(x.world4)
'''
这里我们并没有world4属性,在找不到属性的情况下,正常的继承object的对象都会抛出AtrributeError的错误。但是这里我通过__getattr__魔法方法改变了找不到属性时候的类的行为。输出了查找的属性的参数。
'''
  • __setattr__ 是设置参数的时候会调用到的魔法方法,相当于设置参数前的一个钩子。每个设置属性的方法都绕不开这个魔法方法,只有拥有这个魔法方法的对象才可以设置属性。在使用这个方法的时候要特别注意到不要被循环调用了
class Test(object):
    def __init__(self, world):
        self.world = world

    def __setattr__(self, name, value):
        if name == 'value':
            object.__setattr__(self, name, value - 100)
        else:
            object.__setattr__(self, name, value)

x = Test(123)
print x.world
x.value = 200
print x.value

output:
123
100
  • __delattr____setattr__特别相似,同样需要注意的也是循环调用问题,其他都差不多,只是把属性赋值变成了 del self.name这样的表示。下面直接上个例子,不再多赘述。
class Test(object):
    def __init__(self, world):
        self.world = world

    def __delattr__(self, item):
        print 'hahaha del something'
        object.__delattr__(self, item)


x = Test(123)
del x.world
print x.world

output:
hahaha del something
Traceback (most recent call last):
  File "/Users/piperck/Desktop/py_pra/laplace_pra/practie_01_23/c2.py", line 12, in <module>
    print x.world
AttributeError: 'Test' object has no attribute 'world'
  • getattributegetattr方法唯一不同的地方是,上面我们已经介绍了getattr方法只能在找不到属性的时候拦截调用,然后进行重载或者加入一些其他操作。但是getattribute`更加强大,他可以拦截所有的属性获取。所以也容易出现我们上面提到的,循环调用的问题。下面上一个例子来说明这个问题:
class Test(object):
    def __init__(self, world):
        self.world = world

    def __getattribute__(self, item):
        print 'get_something: %s' % item
        return item


x = Test(123)
print x.world
print x.pp

output:
get_something: world
world
get_something: pp
pp
'''
可以看到,区别于__getattr__只拦截不存在的属性,__getattribute__会拦截所有的属性。所以导致了已经被初始化的world值123,也被改写成了字符串world。而不存在的属性也被改写了成了pp。
'''
  • __del__ 定义当一个类的实例对象内存被销毁前的行为
  • __str____repr__却别
class Test(object):
    def __init__(self, world):
        self.world = world

    def __str__(self):
        return 'world is %s str' % self.world

    def __repr__(self):
        return 'world is %s repr' % self.world

t = Test('world_big')
print str(t)
print repr(t)

output:
world is world_big str
world is world_big repr
'''其实__str__相当于是str()方法 而__repr__相当于repr()方法。str是针对于让人更好理解的字符串格式化,而repr是让机器更好理解的字符串格式化'''

8,面向对象中怎么实现只读属性

  • 属性私有化
  • @property 其实@property装饰器就是把class的方法变成属性
class Test(object):
    def __init__(self):
        # 私有化属性
        self.__age = 18

    # 外界可以调用此函数间接访问私有属性
    def get_age(self):
        return self.__age

    # 可以像调用属性一样调用方法
    @property
    def age(self):
        return self.__age

test = Test()
test.get_age()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值