পাইথনে উদাহরণ পরিবর্তনগুলি কীভাবে পাবেন?


120

সমস্ত শ্রেণীর উদাহরণ ভেরিয়েবলের অ্যারে পেতে পাইথনে কি বিল্ট-ইন পদ্ধতি রয়েছে? উদাহরণস্বরূপ, যদি আমার এই কোডটি থাকে:

class hi:
  def __init__(self):
    self.ii = "foo"
    self.kk = "bar"

আমার এটি করার কোনও উপায় আছে:

>>> mystery_method(hi)
["ii", "kk"]

সম্পাদনা: আমি প্রাথমিকভাবে ভ্রান্তভাবে ক্লাস ভেরিয়েবলের জন্য বলেছিলাম।


আপনার উদাহরণ "উদাহরণ ভেরিয়েবলগুলি" দেখায়। ক্লাস ভেরিয়েবল অন্য জিনিস।
এস্লট

উত্তর:


143

প্রতিটি বস্তুর একটি __dict__ভেরিয়েবল থাকে যাতে সমস্ত ভেরিয়েবল এবং এর মান থাকে।

এটা চেষ্টা কর

>>> hi_obj = hi()
>>> hi_obj.__dict__.keys()

7
এফডাব্লুআইডাব্লু, পরিদর্শন মডিউল আপনাকে ডিকের উপর নির্ভর করার চেয়ে আরও নির্ভরযোগ্য পদ্ধতি দেয় যা সমস্ত দৃষ্টান্তেই নয়।
থমাস ওয়াউটারস

1
কোন ধরণের উদাহরণটিতে ডিক নেই ? আমি কখনই এর মুখোমুখি হই নি।
কার্ল মায়ার

3
কিছু অন্তর্নির্মিত প্রকার, যেমন ইনট। "X = 5" এবং তারপরে "x .__ ডিক__" বলার চেষ্টা করুন এবং আপনি একটি অ্যাট্রিবিউটেরিয়ার পাবেন
এলি কোর্টরাইট

6
এছাড়াও, স্লট ব্যবহার করে এমন কিছু ।
টমাস ওয়াউটারস

2
আপনি কেন চেষ্টা করতে চান এবং কোনও int এর ক্লাস উদাহরণ ভেরিয়েবল পেতে চান? এটি এমনকি কোনও শ্রেণি নয় (যদিও আমি এতে ভুল হতে পারি)।
মার্টিন শেরবার্ন

103

ভার্স ব্যবহার করুন ()

class Foo(object):
    def __init__(self):
        self.a = 1
        self.b = 2

vars(Foo()) #==> {'a': 1, 'b': 2}
vars(Foo()).keys() #==> ['a', 'b']

6
+1 আমি ব্যক্তিগতভাবে মনে করি এই বাক্য গঠনটি ডিক ব্যবহারের চেয়ে পরিষ্কার , যেহেতু ডাবল আন্ডারস্কোর সহ বৈশিষ্ট্যগুলি পাইথন সিনট্যাক্সে "ব্যক্তিগত" বলে মনে করা হয়।
মার্টিন ডাব্লু

3
@ মার্টিন: __methodব্যক্তিগত, __method__এটি একটি বিশেষ পদ্ধতি, অগত্যা ব্যক্তিগত নয়; আমি বলতে চাই বিশেষ পদ্ধতিগুলি পদ্ধতির পরিবর্তে কোনও বস্তুর ক্যাপাবিলাইট সংজ্ঞায়িত করে।
u0b34a0f6ae

2
__method__বেশ কুরুচিপূর্ণ, এবং আমি মনে করি যে একেবারে প্রয়োজন না হলে লোকেরা তাদের ব্যবহার থেকে বিরত রাখতে চেষ্টা এবং বিরত রাখার জন্য তাদের নামকরণ করা হয়েছে। এক্ষেত্রে আমাদের বিকল্প বিকল্প () রয়েছে।
মার্টিন শেরবার্ন

আমার ক্ষেত্রে আমি Vars কলিং চেষ্টা (ObjName) এবং একটি অভিধান যার চাবি দেওয়া বর্গ / বস্তুর পদ্ধতি আছে, কিন্তু কোন চিহ্ন সঙ্গে একটি dict_proxy ফেরৎ Init উপাদান। কোন অনুমান কেন?
ব্যবহারকারী 228137

ডাবল আন্ডারস্কোর ভেরিয়েবল __str__, __method__নিজেই স্বাভাবিকভাবে ভাষার জন্য হয়। তুমি কি করলে str(something)?
Zizouz212

15

আপনি সাধারণত উদাহরণস্বরূপ কেবলমাত্র একটি শ্রেণীর দেওয়া বৈশিষ্ট্যগুলি পেতে পারেন না, অন্তত ক্লাসটি ইনস্ট্যান্ট না করে না। উদাহরণস্বরূপ প্রদত্ত উদাহরণ বৈশিষ্ট্যগুলি পেতে পারেন, যদিও শ্রেণীর বৈশিষ্ট্যগুলি দেওয়া হয়েছে। 'পরিদর্শন করুন' মডিউলটি দেখুন। আপনি উদাহরণের বৈশিষ্ট্যের তালিকা পেতে পারেন না কারণ উদাহরণগুলিতে অ্যাট্রিবিউট হিসাবে সত্যই কিছু থাকতে পারে এবং - যেমন আপনার উদাহরণ হিসাবে - এগুলি তৈরির সাধারণ উপায় হ'ল __init__ পদ্ধতিতে কেবল তাদের অর্পণ করা।

একটি ব্যতিক্রম হ'ল যদি আপনার শ্রেণি স্লট ব্যবহার করে, যা শ্রেণীর উদাহরণগুলির জন্য শ্রেণীবদ্ধ বৈশিষ্ট্যগুলির একটি নির্দিষ্ট তালিকা attrib স্লটগুলি http://www.python.org/2.2.3/descintsro.html এ ব্যাখ্যা করা হয়েছে , তবে স্লট সহ বিভিন্ন সমস্যা রয়েছে; তারা মেমরি বিন্যাসকে প্রভাবিত করে, তাই একাধিক উত্তরাধিকার সমস্যাযুক্ত হতে পারে এবং সাধারণভাবে উত্তরাধিকারগুলিও স্লটগুলিকে বিবেচনায় নিতে হয়।


ডাউনভোটিং কারণ "আপনি উদাহরণের বৈশিষ্ট্যের একটি তালিকা পেতে পারেন না" কেবল ভুল: উভয় ভার () এবং ডিক আপনাকে ঠিক তা দেয়।
কার্ল মায়ার

2
আমি ধরে নিলাম তার অর্থ "আপনি সম্ভাব্য সমস্ত উদাহরণের বৈশিষ্ট্যগুলির তালিকা পেতে পারেন না"। উদাহরণস্বরূপ, আমি প্রায়শই প্রথম অনুরোধ করার সময় একটি উদাহরণ পরিবর্তনশীল যুক্ত করতে অলস প্রজন্ম এবং @ প্রপার্টি ডেকরেটার ব্যবহার করি। ডিক ব্যবহার করা আপনাকে এই পরিবর্তনশীল সম্পর্কে একবার বলার আগে উপস্থিত ছিল তবে তা আগে নয়।
এলি কোর্টরাইট

5
আমি ডাউনওয়েট করি নি, এবং দয়া করে লক্ষ্য করুন যে আমি আসলে কী বলেছি: আপনি কেবলমাত্র একটি শ্রেণীর দেওয়া উদাহরণ বৈশিষ্ট্যের একটি তালিকা পেতে পারেন না , এটিই প্রশ্নের সাথে সংযুক্ত কোডটি করার চেষ্টা করে।
থমাস ওয়াউটারস

2
@ কার্ল: আপনার জ্ঞানের অভাবের ভিত্তিতে মিথ্যা মন্তব্য এবং ডাউনভোটিং লেখার আগে দয়া করে নিজেকে শিক্ষিত করুন।
নিকো

14

ওপি পোস্ট করা উদাহরণের জন্য ভার () এবং ডিক উভয় পদ্ধতিই কাজ করবে তবে তারা "আলগাভাবে" সংজ্ঞায়িত বস্তুর জন্য কাজ করবে না যেমন:

class foo:
  a = 'foo'
  b = 'bar'

সমস্ত অ-কলযোগ্য বৈশিষ্ট্য মুদ্রণ করতে, আপনি নিম্নলিখিত ফাংশনটি ব্যবহার করতে পারেন:

def printVars(object):
    for i in [v for v in dir(object) if not callable(getattr(object,v))]:
        print '\n%s:' % i
        exec('print object.%s\n\n') % i

5
exec('print object.%s\n\n') % iএভাবে লিখতে হবেprint getattr(object, i)
user102008

11

আপনি যদি পরীক্ষা করতে পারেন যে কোনও জিনিসের সাথে একটি নির্দিষ্ট ভেরিয়েবল রয়েছে:

>>> hi_obj = hi()
>>> hasattr(hi_obj, "some attribute")

6

আপনার উদাহরণটি "উদাহরণের ভেরিয়েবলগুলি" দেখায়, প্রকৃতপক্ষে শ্রেণীর ভেরিয়েবলগুলি নয়।

অল্পক্ষণের hi_obj.__class__.__dict__.items()বর্গ ভেরিয়েবলের জন্য, সদস্য ফাংশন মত অন্যান্য অন্যান্য বর্গ সদস্য ও ধারণকারী মডিউল করেন।

class Hi( object ):
    class_var = ( 23, 'skidoo' ) # class variable
    def __init__( self ):
        self.ii = "foo" # instance variable
        self.jj = "bar"

ক্লাসের ভেরিয়েবলগুলি ক্লাসের সমস্ত দৃষ্টান্ত দ্বারা ভাগ করা হয়।


6

সুপারিশ

>>> print vars.__doc__
vars([object]) -> dictionary

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.

অন্য শব্দগুলিতে এটি মূলত কেবল __dict__


5

যদিও ওপি প্রশ্নের সরাসরি উত্তর না হলেও, একটি কার্যক্রমে কী ভেরিয়েবলের সুযোগ রয়েছে তা খুঁজে বের করার একটি দুর্দান্ত মিষ্টি উপায় রয়েছে। এই কোডটি একবার দেখুন:

>>> def f(x, y):
    z = x**2 + y**2
    sqrt_z = z**.5
    return sqrt_z

>>> f.func_code.co_varnames
('x', 'y', 'z', 'sqrt_z')
>>> 

ফানকোড অ্যাট্রিবিউটে এতে সমস্ত ধরণের আকর্ষণীয় জিনিস রয়েছে। এটি আপনাকে কিছু দুর্দান্ত জিনিস টুড করতে দেয়। আমি কীভাবে এটি ব্যবহার করেছি তার উদাহরণ এখানে দেওয়া হয়েছে:

def exec_command(self, cmd, msg, sig):

    def message(msg):
        a = self.link.process(self.link.recieved_message(msg))
        self.exec_command(*a)

    def error(msg):
        self.printer.printInfo(msg)

    def set_usrlist(msg):
        self.client.connected_users = msg

    def chatmessage(msg):
        self.printer.printInfo(msg)

    if not locals().has_key(cmd): return
    cmd = locals()[cmd]

    try:
        if 'sig' in cmd.func_code.co_varnames and \
                       'msg' in cmd.func_code.co_varnames: 
            cmd(msg, sig)
        elif 'msg' in cmd.func_code.co_varnames: 
            cmd(msg)
        else:
            cmd()
    except Exception, e:
        print '\n-----------ERROR-----------'
        print 'error: ', e
        print 'Error proccessing: ', cmd.__name__
        print 'Message: ', msg
        print 'Sig: ', sig
        print '-----------ERROR-----------\n'

2

নিম্নলিখিতটি পেতে ডার্কের উত্তরে তৈরি, যা আপনি স্প্রিন্টফের সমতুল্য চাই এবং আশা করি যে কাউকে সহায়তা করবে ...

def sprint(object):
    result = ''
    for i in [v for v in dir(object) if not callable(getattr(object, v)) and v[0] != '_']:
        result += '\n%s:' % i + str(getattr(object, i, ''))
    return result

0

কখনও কখনও আপনি পাবলিক / প্রাইভেট ওয়ারগুলির উপর ভিত্তি করে তালিকাটি ফিল্টার করতে চান। যেমন

def pub_vars(self):
    """Gives the variable names of our instance we want to expose
    """
    return [k for k in vars(self) if not k.startswith('_')]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.